在pandas中,我经常使用以下内容按出现次数过滤数据帧
df = df.groupby('A').filter(lambda x: len(x) >= THRESHOLD)
Run Code Online (Sandbox Code Playgroud)
假设df有另一列'B',我想通过该列上的唯一值计数来过滤数据帧,我希望像
df = df.groupby('A').filter(lambda x: len(np.unique(x['B'])) >= THRESHOLD2)
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用,什么是正确的方法?
jez*_*ael 10
它应该很好用nunique:
df = pd.DataFrame({'B':list('abccee'),
'E':[5,3,6,9,2,4],
'A':list('aabbcc')})
print (df)
A B E
0 a a 5
1 a b 3
2 b c 6
3 b c 9
4 c e 2
5 c e 4
THRESHOLD2 = 2
df1 = df.groupby('A').filter(lambda x: x['B'].nunique() >= THRESHOLD2)
print (df1)
A B E
0 a a 5
1 a b 3
Run Code Online (Sandbox Code Playgroud)
但如果需要更快的解决方案使用transform和筛选boolean indexing:
df2 = df[df.groupby('A')['B'].transform('nunique') >= THRESHOLD2]
print (df2)
A B E
0 a a 5
1 a b 3
Run Code Online (Sandbox Code Playgroud)
时间:
np.random.seed(123)
N = 1000000
L = list('abcde')
df = pd.DataFrame({'B': np.random.choice(L, N, p=(0.75,0.0001,0.0005,0.0005,0.2489)),
'A':np.random.randint(10000,size=N)})
df = df.sort_values(['A','B']).reset_index(drop=True)
print (df)
THRESHOLD2 = 3
In [403]: %timeit df.groupby('A').filter(lambda x: x['B'].nunique() >= THRESHOLD2)
1 loop, best of 3: 3.05 s per loop
In [404]: %timeit df[df.groupby('A')['B'].transform('nunique')>= THRESHOLD2]
1 loop, best of 3: 558 ms per loop
Run Code Online (Sandbox Code Playgroud)
警告
考虑到组的数量,结果不能解决性能问题,这将对某些解决方案的时序产生很大影响.
| 归档时间: |
|
| 查看次数: |
1728 次 |
| 最近记录: |