Bri*_*tow 0 python scipy percentile pandas
我遇到了一个奇怪的情况,pd.describe 给我的百分位标记与 scipy.stats percentileofscore 不一致,我认为是因为 NaN。
我的 df 是:
f_recommend
0 3.857143
1 4.500000
2 4.458333
3 NaN
4 3.600000
5 NaN
6 4.285714
7 3.587065
8 4.200000
9 NaN
Run Code Online (Sandbox Code Playgroud)
当我跑步时df.describe(percentiles=[.25, .5, .75])我得到:
f_recommend
count 7.000000
mean 4.069751
std 0.386990
min 3.587065
25% 3.728571
50% 4.200000
75% 4.372024
max 4.500000
Run Code Online (Sandbox Code Playgroud)
当我删除 NaN 运行时,我得到相同的值。
然而,当我想查找特定值时,当我运行时,scipy.stats.percentileofscore(df['f_recommend'], 3.61, kind = 'mean')我得到:第 28 个百分位数包含 NaN,第 20 个百分位数不包含 NaN。
有什么想法可以解释这种差异吗?
预计到达时间:
我不认为问题在于我们计算百分位数的方式不同。因为只有当您以不同的方式计算相同的两个数字的百分位数时,这才重要。但在这里,describe 给出的 25 个百分位为 3.72。所以 3.61 绝对不可能是第 28 个百分位。没有一个公式可以给出这一点。
特别是,当我对不带 NaN 的 6 个值使用描述时,我得到相同的值,因此忽略 NaN,这很好。但是当我在没有 NaN 的情况下运行分数百分位时,我得到一个不匹配的数字。
预计到达时间 2:
更简单的例子:
In [48]: d = pd.DataFrame([1,2,3,4,5,6,7])
In [49]: d.describe()
Out[49]:
0
count 7.000000
mean 4.000000
std 2.160247
min 1.000000
25% 2.500000
50% 4.000000
75% 5.500000
max 7.000000
In [50]: sp.stats.percentileofscore(d[0], 2.1, kind = 'mean')
Out[50]: 28.571428571428573
Run Code Online (Sandbox Code Playgroud)
“kind”参数并不重要,因为 2.1 是唯一的。
scipy.stats.percentileofscore不忽略nan,也不检查该值并以某种特殊方式处理它。它只是数据中的另一个浮点值。percentileofscore这意味着with data contains的行为是未定义的,因为in 比较nan的行为:nan
In [44]: np.nan > 0
Out[44]: False
In [45]: np.nan < 0
Out[45]: False
In [46]: np.nan == 0
Out[46]: False
In [47]: np.nan == np.nan
Out[47]: False
Run Code Online (Sandbox Code Playgroud)
这些结果都是正确的——这就是nan应该的行为方式。但这意味着,为了知道如何percentileofscore处理nan,您必须知道代码如何进行比较。这是您不必知道的实现细节,并且您不能依赖它在 scipy 的未来版本中相同。
如果您研究 的行为percentfileofscore,您会发现它的行为就像nan是无限的。例如,如果您替换nan为大于输入中任何其他值的值,您将得到相同的结果:
In [53]: percentileofscore([10, 20, 25, 30, np.nan, np.nan], 18)
Out[53]: 16.666666666666664
In [54]: percentileofscore([10, 20, 25, 30, 999, 999], 18)
Out[54]: 16.666666666666664
Run Code Online (Sandbox Code Playgroud)
不幸的是,您不能依赖这种行为。如果将来实现发生变化,最终nan可能会表现得像负无穷大,或者有其他一些未指定的行为。
这个“问题”的解决方案很简单:不要给出percentileofscore任何nan值。您必须先清理数据。请注意,这可以很简单:
result = percentileofscore(a[~np.isnan(a)], score)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |