如何指定运行在先前记录上的pandas groupby操作?

时间:2018-05-30 07:40:45

标签: python pandas dataframe group-by pandas-groupby

我有一个如下的Pandas数据帧,必须按Col_2排序:

+----+-------+-------+ 
| id | Col_1 | Col_2 |
+----+-------+-------+
|  1 |     0 |    21 |
|  1 |     1 |    24 |
|  1 |     1 |    32 |
|  1 |     0 |    35 |
|  1 |     1 |    37 |
|  2 |     0 |     2 |
|  2 |     0 |     5 |
+----+-------+-------+

如何创建两个新列:

Col_1_sum:每个id的前一行中的值的总和。 Col_2_max:Col_1为1的最后一行中Col_2的最大值。 (对于每个id)

例如,对于上面的数据帧,结果应为:

+----+-------+-------+-----------+-----------+
| id | Col_1 | Col_2 | Col_1_Sum | Col_2_Max |
+----+-------+-------+-----------+-----------+
|  1 |     0 |    21 |         0 |         0 |
|  1 |     1 |    24 |         0 |         0 |
|  1 |     1 |    32 |         1 |        24 |
|  1 |     0 |    35 |         2 |        32 |
|  1 |     1 |    37 |         2 |        32 |
|  2 |     0 |     2 |         0 |         0 |
|  2 |     0 |     5 |         0 |         0 |
+----+-------+-------+-----------+-----------+

1 个答案:

答案 0 :(得分:4)

你有两个问题。一次一个。

您的第一个问题已通过groupbyshiftcumsum回答:

df.groupby('id').Col_1.apply(lambda x: x.shift().cumsum())

0    NaN
1    0.0
2    1.0
3    2.0
4    2.0
5    NaN
6    0.0
Name: Col_1, dtype: float64

或者,如果您更喜欢清洁输出,

df.groupby('id').Col_1.apply(lambda x: x.shift().cumsum()).fillna(0).astype(int)

0    0
1    0
2    1
3    2
4    2
5    0
6    0
Name: Col_1, dtype: int64

您的第二个,也是类似的,使用groupbyshiftcummaxffill

df.Col_2.where(df.Col_1.eq(1)).groupby(df.id).apply(
    lambda x: x.shift().cummax().ffill()
)

0     NaN
1     NaN
2    24.0
3    32.0
4    32.0
5     NaN
6     NaN
Name: Col_2, dtype: float64

在这两种情况下,基本成分是groupby,然后是随后的轮班调用。请注意,由于要对子组执行多个操作,因此很难解决这些答案apply

考虑通过定义自定义函数来取出lambda。您可以在较大的数据上保存几个周期。