繁体   English   中英

使用基于组的条件删除一些Pandas数据帧行

[英]Drop some Pandas dataframe rows using group based condition

比方说,我有一些关于销售的数据,并希望了解不同的邮政编码如何比较:有些提供比其他更有利可图的业务吗? 所以我通过邮政编码进行分组,并且可以根据每个邮政编码轻松获得各种统计数据。 然而,有一些非常高价值的工作会扭曲统计数据,所以我想做的就是忽略异常值。 由于各种原因,我想要做的是按组定义异常值:例如,删除数据框中位于其组的顶部x百分位数中的行,或其组中的前n个。

所以,如果我有以下数据框:

>>> df
Out[67]: 
     A         C         D
0  foo -0.536732  0.061055
1  bar  1.470956  1.350996
2  foo  1.981810  0.676978
3  bar -0.072829  0.417285
4  foo -0.910537 -1.634047
5  bar -0.346749 -0.127740
6  foo  0.959957 -1.068385
7  foo -0.640706  2.635910

我希望能够有一些函数,比如drop_top_n(df, group_column, value_column, number_to_drop) ,其中drop_top_n(df, "A", "C", 2)将返回

     A         C         D
0  foo -0.536732  0.061055
4  foo -0.910537 -1.634047
5  bar -0.346749 -0.127740
7  foo -0.640706  2.635910

使用filter会丢弃整个组,而不是组的一部分。

我想,我可以遍历这些组,并且每个组都要找出要删除的行,然后返回到原始数据帧并删除它们,但这看起来非常笨拙。 有没有更好的办法?

在0.13你可以使用cumcount

In [11]: df[df.sort('C').groupby('A').cumcount(ascending=False) >= 2]  # use .sort_index() to remove UserWarning
Out[11]: 
     A         C         D
0  foo -0.536732  0.061055
4  foo -0.910537 -1.634047
5  bar -0.346749 -0.127740
7  foo -0.640706  2.635910

[4 rows x 3 columns]

首先排序可能更有意义:

In [21]: df = df.sort('C')

In [22]: df[df.groupby('A').cumcount(ascending=False) >= 2]
Out[22]: 
     A         C         D
4  foo -0.910537 -1.634047
7  foo -0.640706  2.635910
0  foo -0.536732  0.061055
5  bar -0.346749 -0.127740

[4 rows x 3 columns]

您可以使用apply()方法:

import pandas as pd
import io


txt="""     A         C         D
0  foo -0.536732  0.061055
1  bar  1.470956  1.350996
2  foo  1.981810  0.676978
3  bar -0.072829  0.417285
4  foo -0.910537 -1.634047
5  bar -0.346749 -0.127740
6  foo  0.959957 -1.068385
7  foo -0.640706  2.635910"""

df = pd.read_csv(io.BytesIO(txt), delim_whitespace=True, index_col=0)

def f(df):
    return df.sort("C").iloc[:-2]
df2 = df.groupby("A", group_keys=False).apply(f)
print df2

输出:

     A         C         D
5  bar -0.346749 -0.127740
4  foo -0.910537 -1.634047
7  foo -0.640706  2.635910
0  foo -0.536732  0.061055

如果您想要原始订单:

print df2.reindex(df.index[df.index.isin(df2.index)])

输出:

    A         C         D
0  foo -0.536732  0.061055
4  foo -0.910537 -1.634047
5  bar -0.346749 -0.127740
7  foo -0.640706  2.635910

获取组上方的行意味着:

def f(df):
    return df[df.C>df.C.mean()]
df3 = df.groupby("A", group_keys=False).apply(f)
print df3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM