对dataframe groupby的迭代

时间:2018-03-03 11:29:02

标签: python pandas

       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

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

1 个答案:

答案 0 :(得分: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~列中的行和df2 = df[~df['A'].isin(df1['A'])].drop_duplicates('A', keep='last') print (df2) A B C point 5 Jack 21 -1 -19 的倒置条件,再次isin仅保留最后一行:

dict comprehension

最后使用drop_duplicates 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}

{
    "_id" : "5a5ffef0869422169c7aa01b",
    "email" : "example@gmail.com", 
    "checkin" : "2018-2-28 5:12",
    "checkout" : "2018-2-28 6:12",
}