对dataframe groupby的迭代

问题描述 投票:3回答:1
       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。
  • 对“莎拉”组:df["Point"]是第一个B值乘以C值的乘法。 23 *( - 2)=( - 46); 23 * 4 = 92。
  • 对于“杰克”组: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])

得到这个results

      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

我想我必须进行双重迭代,但我不知道如何,或者是否有可能以不同的方式做到这一点。

python pandas
1个回答
3
投票

首先使用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

最后使用concatdict 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}
© www.soinside.com 2019 - 2024. All rights reserved.