比方说,我有一些关于销售的数据,并希望了解不同的邮政编码如何比较:有些提供比其他更有利可图的业务吗?所以我通过邮政编码进行分组,并且可以根据每个邮政编码轻松获得各种统计数据.然而,有一些非常高价值的工作扭曲了统计数据,所以我想做的就是忽略异常值.由于各种原因,我想要做的是按组定义异常值:例如,删除数据框中位于其组的顶部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
Run Code Online (Sandbox Code Playgroud)
我希望能够有一些功能,比如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
Run Code Online (Sandbox Code Playgroud)
使用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]
Run Code Online (Sandbox Code Playgroud)
首先排序可能更有意义:
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]
Run Code Online (Sandbox Code Playgroud)
您可以使用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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
如果您想要原始订单:
print df2.reindex(df.index[df.index.isin(df2.index)])
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
获取高于组平均值的行:
def f(df):
return df[df.C>df.C.mean()]
df3 = df.groupby("A", group_keys=False).apply(f)
print df3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3328 次 |
| 最近记录: |