【问题标题】:Pandas quantile failing with NaN's present熊猫分位数因 NaN 的存在而失败
【发布时间】:2014-07-25 15:00:31
【问题描述】:

我在计算四分位间距时遇到了一个有趣的情况。假设我们有一个数据框,例如:

import pandas as pd
index=pd.date_range('2014 01 01',periods=10,freq='D')
data=pd.np.random.randint(0,100,(10,5))
data = pd.DataFrame(index=index,data=data)

data
Out[90]: 
             0   1   2   3   4
2014-01-01  33  31  82   3  26
2014-01-02  46  59   0  34  48
2014-01-03  71   2  56  67  54
2014-01-04  90  18  71  12   2
2014-01-05  71  53   5  56  65
2014-01-06  42  78  34  54  40
2014-01-07  80   5  76  12  90
2014-01-08  60  90  84  55  78
2014-01-09  33  11  66  90   8
2014-01-10  40   8  35  36  98

# test for q1 values (this works)
data.quantile(0.25)
Out[111]: 
0    40.50
1     8.75
2    34.25
3    17.50
4    29.50

# break it by inserting row of nans
data.iloc[-1] = pd.np.NaN

data.quantile(0.25)
Out[115]: 
0    42
1    11
2    34
3    12
4    26

第一个四分位数可以通过取数据框中低于整体中位数的值的中位数来计算,因此我们可以看到 data.quantile(0.25) 应该产生的结果。例如

med = data.median()
q1  = data[data<med].median()
q1
Out[119]: 
0    37.5
1     8.0
2    19.5
3    12.0
4    17.0

似乎分位数未能提供 q1 等的适当表示,因为它在处理 NaN 值方面做得不好(即它在没有 NaN 的情况下工作,但在 NaN 的情况下不工作)。

我认为这可能不是“NaN”问题,而可能是无法处理偶数数据集的分位数(即必须将中位数计算为两个中心数的平均值)。但是,在使用具有偶数行和奇数行的数据帧进行测试后,我发现分位数正确地处理了这些情况。只有当数据框中存在 NaN 值时,才会出现问题。

我想使用 quntile 来计算我的数据框中的滚动 q1/q3 值,但是,这不适用于 NaN 的存在。任何人都可以提供这个问题的解决方案吗?

【问题讨论】:

  • 你试过df.dropna()吗?
  • 我已经应用了 dropna(how='all'),这使我的示例具有误导性。但是,我不愿意应用 dropna(how='any'),因为我不想仅仅因为 NaN 位于下一列中而丢失有效数据。你的建议很好。话虽如此,分位数似乎仍然存在一个基本问题(或者我认为!)。
  • 对不起,祝你好运!
  • 您确定结果应该是data[data&lt;med].median() 而不是data[data&lt;=med].median()
  • 这(@alko 的评论上方)确实给出了与熊猫分位数相同的结果

标签: python-2.7 pandas quantile


【解决方案1】:

在内部,quantile 在非空值上使用numpy.percentile。当您将 data 的最后一行更改为 NaNs 时,您实际上在第一列中留下了一个数组 array([ 33., 46., 71., 90., 71., 42., 80., 60., 33.])

计算 np.percentile(array([ 33., 46., 71., 90., 71., 42., 80., 60., 33.]) 得到 42。

来自文档字符串:

给定一个长度为 N 的向量 V,V 的第 q 个百分位数是第 q 个排名 V 的排序副本中的值。两个最近的加权平均值 如果归一化排名与 q 不完全匹配,则使用邻居。 q=50 与中位数相同,q=0 与最小值相同 如果q=100,则与最大值相同。

【讨论】:

  • 另外,如果你直接使用np.percentile(带有NaN),例如使用df2.apply(np.percentile, args=[25]),你会给出其他值,因为在计算分位数之前NaN不会像熊猫一样被删除。
  • @TomAugspurger 代码 np.percentile(np.array([ 33., 46., 71., 90., 71., 42., 80., 60., 33.], 0.25) 返回 32.999,而不是 42。我认为使用 np.quantile() 可以返回 42,代码 np.quantile(np.array([ 33., 46., 71., 90., 71., 42., 80., 60., 33.], 0.25) 返回 42。
猜你喜欢
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 2018-07-05
  • 2016-05-10
  • 1970-01-01
相关资源
最近更新 更多