消除给定百分位数上的所有数据

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 &lt; df.quantile(.95)]?如果不在范围内,我希望所有值都被过滤掉,如果需要,用NaN 替换。 基本相同但更简洁:df.query('a &lt; a.quantile(.95)')。如果列名较长可以提高可读性:col = 'some_verbose_metric_name'; df.query(f'col &lt; 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 .. 分位数函数是不是需要排序数据来计算百分位数?

Python机器学习——百分位数

在 SQL 中分析并形成分位数并计算落在各个分位数中的值的百分比

JavaScript中的分位数/百分点/百分位数/逆累积分布函数

深入浅出统计学02