我有一个df,我想基于分组筛选出一列。我希望按组合保持分组({cc
,odd
,tree1
和tree2
),如果天> 4,然后保留,否则放弃
df = pd.DataFrame()
df['cc'] = ['BB', 'BB', 'BB', 'BB','BB', 'BB','BB', 'BB', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ']
df['odd'] = [3434, 3434, 3434, 3434, 3435, 3435, 3435, 3435, 3434, 3434, 3434, 3434, 3435, 3435, 3435, 3435, 3434, 3434, 3434, 3434, 3435, 3435, 3435, 3435]
df['tree1'] = ['ASP', 'ASP', 'ASP', 'ASP', 'SAP', 'SAP', 'SAP', 'SAP', 'ASP', 'ASP', 'ASP', 'ASP', 'SAP', 'SAP', 'SAP', 'SAP', 'ASP', 'ASP', 'ASP', 'ASP', 'SAP', 'SAP', 'SAP', 'SAP']
df['tree2'] = ['ATK', 'ATK','ATK','ATK','ATK','ATK','ATK','ATK', 'ATK', 'ATK','ATK','ATK','ATK','ATK','ATK','ATK', 'ATK', 'ATK','ATK','ATK','ATK','ATK','ATK','ATK']
df['day'] = [1, 2, 3, 4, 3, 4, 5, 6, 2, 3, 4, 5, 1, 3, 5, 7, 1, 2, 6, 8, 2, 4, 6, 8]
df
我尝试了这个但是这会丢弃任何一行,其中日值小于4
df_grouped = df.groupby(['cc', 'odd', 'tree1', 'tree2']).filter(df['day'] > 4)
我收到此错误TypeError: 'Series' object is not callable
试过这个
df_grouped = df.groupby(['cc', 'odd', 'tree1', 'tree2']).filter(lambda x: x['day'] > 4)
我收到此错误TypeError: filter function returned a Series, but expected a scalar bool
。
我搜索并尝试解决这些错误,但建议的解决方案对我不起作用。我想得到如下的df:
df1 = pd.DataFrame()
df1['cc'] = ['BB', 'BB','BB', 'BB', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'DD', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ', 'ZZ']
df1['odd'] = [3435, 3435, 3435, 3435, 3434, 3434, 3434, 3434, 3435, 3435, 3435, 3435, 3434, 3434, 3434, 3434, 3435, 3435, 3435, 3435]
df1['tree1'] = ['SAP', 'SAP', 'SAP', 'SAP', 'ASP', 'ASP', 'ASP', 'ASP', 'SAP', 'SAP', 'SAP', 'SAP', 'ASP', 'ASP', 'ASP', 'ASP', 'SAP', 'SAP', 'SAP', 'SAP']
df1['tree2'] = ['ATK','ATK','ATK','ATK', 'ATK', 'ATK','ATK','ATK','ATK','ATK','ATK','ATK', 'ATK', 'ATK','ATK','ATK','ATK','ATK','ATK','ATK']
df1['day'] = [3, 4, 5, 6, 2, 3, 4, 5, 1, 3, 5, 7, 1, 2, 6, 8, 2, 4, 6, 8]
df1
我尝试使用any
的逻辑功能,但我无法使其正常工作,它只返回True
或False
而不是过滤的数据帧。
答案 0 :(得分:3)
现在我已经理解了你想要的东西,让我们试试transform
+ any
:
df[df.assign(key=df.day > 4)
.groupby(['cc', 'odd', 'tree1', 'tree2']).key.transform('any')
]
或者,
df[df.day.gt(4).groupby([df.cc, df.odd, df.tree1, df.tree2]).transform('any')]
cc odd tree1 tree2 day
4 BB 3435 SAP ATK 3
5 BB 3435 SAP ATK 4
6 BB 3435 SAP ATK 5
7 BB 3435 SAP ATK 6
8 DD 3434 ASP ATK 2
9 DD 3434 ASP ATK 3
10 DD 3434 ASP ATK 4
11 DD 3434 ASP ATK 5
12 DD 3435 SAP ATK 1
13 DD 3435 SAP ATK 3
14 DD 3435 SAP ATK 5
15 DD 3435 SAP ATK 7
16 ZZ 3434 ASP ATK 1
17 ZZ 3434 ASP ATK 2
18 ZZ 3434 ASP ATK 6
19 ZZ 3434 ASP ATK 8
20 ZZ 3435 SAP ATK 2
21 ZZ 3435 SAP ATK 4
22 ZZ 3435 SAP ATK 6
23 ZZ 3435 SAP ATK 8
答案 1 :(得分:2)
你想要的IIUC:
In[116]:
df_grouped = df.groupby(['cc', 'odd', 'tree1', 'tree2']).filter(lambda x: (x['day'] > 4).any())
df_grouped
Out[116]:
cc odd tree1 tree2 day
4 BB 3435 SAP ATK 3
5 BB 3435 SAP ATK 4
6 BB 3435 SAP ATK 5
7 BB 3435 SAP ATK 6
8 DD 3434 ASP ATK 2
9 DD 3434 ASP ATK 3
10 DD 3434 ASP ATK 4
11 DD 3434 ASP ATK 5
12 DD 3435 SAP ATK 1
13 DD 3435 SAP ATK 3
14 DD 3435 SAP ATK 5
15 DD 3435 SAP ATK 7
16 ZZ 3434 ASP ATK 1
17 ZZ 3434 ASP ATK 2
18 ZZ 3434 ASP ATK 6
19 ZZ 3434 ASP ATK 8
20 ZZ 3435 SAP ATK 2
21 ZZ 3435 SAP ATK 4
22 ZZ 3435 SAP ATK 6
23 ZZ 3435 SAP ATK 8
因此,这将过滤出组内'day'
值均不大于4的组
<强>定时强>:
%timeit df[df.day.gt(4).groupby([df.cc, df.odd, df.tree1, df.tree2]).transform('any')]
%timeit df.groupby(['cc', 'odd', 'tree1', 'tree2']).filter(lambda x: (x['day'] > 4).any())
%timeit df[df.assign(key=df.day > 4).groupby(['cc', 'odd', 'tree1', 'tree2']).key.transform('any')]
100 loops, best of 3: 5.9 ms per loop
100 loops, best of 3: 5.42 ms per loop
100 loops, best of 3: 3.62 ms per loop
所以@coldspeed的第一种方法是最快的