A B C
0 Bob 10 2
1 Bob 11 8
2 Sarah 23 -2
3 Sarah 24 4
4 Jack 19 -4
5 Jack 21 -1
我想得到一个新的 df["Point"]
如下:
- 对于“Bob”组:
df["Point"]
是第一个 B 值乘以C 值。 10*2=20; 10*8=80。 - 致“Sarah”组:
df["Point"]
是第一个 B 值乘以C 值。 23*(-2)=(-46); 23*4=92。 - 致“Jack”组:
df["Point"]
是第一个 B 值 乘以 C 值。 19*(-4)=(-76); 19*(-1)=(-19)。
我的意思是,我想得到:
A B C Point
0 Bob 10 2 20
1 Bob 11 8 80
2 Sarah 23 -2 -46
3 Sarah 24 4 92
4 Jack 19 -4 -76
5 Jack 21 -1 -19
之后,我想进行以下迭代:
results = {}
grouped = df.groupby("A")
for idx, group in grouped:
if (group["Point"] > 50).any():
results[idx] = group[group["Point"] > 50].head(1)
print ("")
else:
results[idx] = group.tail(1)
print ("")
print(results[idx])
并得到这个结果
:
A B C Point
1 Bob 11 8 80
A B C Point
3 Sarah 23 4 92
A B C Point
5 Jack 21 -1 -19
我想我必须进行两次迭代,但我不知道如何做,也不知道是否可以用不同的方式进行。
最佳答案
首先通过 transform
创建新列与 first
乘以C
专栏:
df['point'] = df.groupby('A')['B'].transform('first').mul(df['C'])
print (df)
A B C point
0 Bob 10 2 20
1 Bob 11 8 80
2 Sarah 23 -2 -46
3 Sarah 24 4 92
4 Jack 19 -4 -76
5 Jack 21 -1 -19
然后首先按条件过滤所有行,然后按 drop_duplicates
仅获取第一行- keep='first'
默认情况下:
df1 = df[df['point'] > 50].drop_duplicates('A')
print (df1)
A B C point
1 Bob 11 8 80
3 Sarah 24 4 92
然后过滤不在df1.A
中的行列 isin
和反转条件 ~
, 再次 drop_duplicates
只保留最后一行:
df2 = df[~df['A'].isin(df1['A'])].drop_duplicates('A', keep='last')
print (df2)
A B C point
5 Jack 21 -1 -19
上次使用 concat
与 dict comprehension
最终 dictionary
:
d = {k: v for k, v in pd.concat([df1, df2]).groupby('A')}
print (d)
{'Bob': A B C point
1 Bob 11 8 80, 'Jack': A B C point
5 Jack 21 -1 -19, 'Sarah': A B C point
3 Sarah 24 4 92}
关于python - 数据框 groupby 的迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49083649/