我有一个如下的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 |
+----+-------+-------+-----------+-----------+
答案 0 :(得分:4)
你有两个问题。一次一个。
您的第一个问题已通过groupby
,shift
和cumsum
回答:
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
您的第二个,也是类似的,使用groupby
,shift
,cummax
和ffill
:
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。您可以在较大的数据上保存几个周期。