消除给定百分位数上的所有数据
Posted
技术标签:
【中文标题】消除给定百分位数上的所有数据【英文标题】:Eliminating all data over a given percentile 【发布时间】:2013-09-05 23:45:59 【问题描述】:我有一个名为 data
的 pandas DataFrame
和一个名为 ms
的列。我想消除 data.ms
高于 95% 的所有行。目前,我正在这样做:
limit = data.ms.describe(90)['95%']
valid_data = data[data['ms'] < limit]
这可行,但我想将其推广到任何百分位数。最好的方法是什么?
【问题讨论】:
【参考方案1】:使用Series.quantile()
方法:
In [48]: cols = list('abc')
In [49]: df = DataFrame(randn(10, len(cols)), columns=cols)
In [50]: df.a.quantile(0.95)
Out[50]: 1.5776961953820687
要过滤掉 df
的行,其中 df.a
大于或等于第 95 个百分位,请执行以下操作:
In [72]: df[df.a < df.a.quantile(.95)]
Out[72]:
a b c
0 -1.044 -0.247 -1.149
2 0.395 0.591 0.764
3 -0.564 -2.059 0.232
4 -0.707 -0.736 -1.345
5 0.978 -0.099 0.521
6 -0.974 0.272 -0.649
7 1.228 0.619 -0.849
8 -0.170 0.458 -0.515
9 1.465 1.019 0.966
【讨论】:
使用pandas,如果我想比较不同的col和特定的分位数,有没有类似numpy广播的快速方法? 删除所有列时是否也有效,即df[df < df.quantile(.95)]
?如果不在范围内,我希望所有值都被过滤掉,如果需要,用NaN
替换。
基本相同但更简洁:df.query('a < a.quantile(.95)')
。如果列名较长可以提高可读性:col = 'some_verbose_metric_name'; df.query(f'col < col.quantile(.95)')
【参考方案2】:
在这类事情上,numpy 比 Pandas 快得多:
numpy.percentile(df.a,95) # attention : the percentile is given in percent (5 = 5%)
等价,但比 :
快 3 倍df.a.quantile(.95) # as you already noticed here it is ".95" not "95"
所以对于您的代码,它给出了:
df[df.a < np.percentile(df.a,95)]
【讨论】:
如果你能负担得起列提取成本,可以确认 numpy 的实现速度要快得多 @2diabolos.com 有没有办法在多个熊猫列上实现百分位过滤器。 类似 df[numpy.logical_and(df.a @deepelement 与列提取成本的权衡是什么?【参考方案3】:您可以使用query 获得更简洁的选项:
df.query('ms < ms.quantile(.95)')
【讨论】:
以上是关于消除给定百分位数上的所有数据的主要内容,如果未能解决你的问题,请参考以下文章
python使用pandas中的groupby函数和agg函数计算每个分组数据的两个分位数(例如百分之10分位数和百分之90分位数)
Pandas .. 分位数函数是不是需要排序数据来计算百分位数?
在 SQL 中分析并形成分位数并计算落在各个分位数中的值的百分比