我有一个奇怪的情况,pd.describe给了我百分位标记,不同意scipy.stats百分之分,因为NaNs,我认为。
我的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
当我运行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
当我移除NaN时,我得到相同的值。
但是,当我想查找特定值时,当我运行scipy.stats.percentileofscore(df['f_recommend'], 3.61, kind = 'mean')
时,我得到:NaN的第28个百分位,而没有的是20。
有什么想法来解释这种差异吗?
ETA:
我不相信问题在于我们以不同的方式计算百分位数。因为这只有在您以不同方式计算相同2个数字的百分位数时才有意义。但在这里,描述给出了25%的百分位数为3.72。所以3.61绝对没有办法可以达到28%。没有一个公式应该给出。
特别是,当我在没有NaN的6个值上使用describe时,我得到相同的值,因此忽略了NaN,这很好。但是当我在没有NaN的情况下运行得分百分比时,我得到的数字并不匹配。
ETA 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
" kind"论证并不重要,因为2.1是独一无二的。
答案 0 :(得分:2)
scipy.stats.percentileofscore
不会忽略nan
,也不会检查值并以某种特殊方式处理它。它只是数据中的另一个浮点值。这意味着percentileofscore
包含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
这些结果都是正确的 - 这就是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
不幸的是,你不能依赖这种行为。如果实施在将来发生变化,nan
可能最终表现为负无穷大,或者有其他一些未指明的行为。
这个“问题”的解决方案很简单:不要给percentileofscore
任何nan
个值。您必须先清理数据。请注意,这可以很简单:
result = percentileofscore(a[~np.isnan(a)], score)
答案 1 :(得分:-1)
答案很简单。
没有普遍接受的计算百分位数的公式,特别是当您的数据包含关系或者无法在相同大小的存储桶中完全分解时。
例如,请查看R
中的文档。有超过七种类型的公式! https://stat.ethz.ch/R-manual/R-devel/library/stats/html/quantile.html
最后,归结为理解使用哪个公式以及差异是否足以成为您案例中的问题。