我有一个像这样的数据框:
total_sum pid
5 2
1 2
6 7
3 7
1 7
1 7
0 7
5 10
1 10
1 10
我想要的是另一列pos
,例如:
total_sum pid pos
5 2 1
1 2 2
6 7 1
3 7 2
1 7 3
1 7 3
0 7 4
5 10 1
1 10 2
1 10 2
背后的逻辑是:
新pos
的初始pid
值为1
。
如果pid
不变,但total_sum
改变,则pos
的值增加1(例如前两行),否则pos
的值就是前一个值(例如最后两行)。
我尝试过的事情:
df['pos'] = 1
df['pos'] = np.where(((df.pid.diff(-1)) == 0 & (df.total_sum.diff(-1) == 0)),
df.pos, (np.where(df.total_sum.diff(1) < 1, df.pos + 1, df.pos )))
当前,我在excel工作表中进行此操作,首先在pos
的第一列中手动编写1,然后在pos
的第二个单元格中编写公式:
=IF(A3<>A2,1,IF(B3=B2,C2,C2+1))
答案 0 :(得分:3)
说明:
对groupby
进行pid
,将相同的pid
分为不同的组。在每个组上,执行以下操作:
_在每个组上致电diff
。 diff
返回整数,或者NaN
表示2个连续行之间的差。每个组的第一行没有上一行,因此diff
总是为每个组的第一行返回NaN
:
df.groupby('pid').total_sum.transform(lambda x: x.diff()
Out[120]:
0 NaN
1 -4.0
2 NaN
3 -3.0
4 -2.0
5 0.0
6 -1.0
7 NaN
8 -4.0
9 0.0
Name: total_sum, dtype: float64
_ ne
检查是否有任何值不是0
。它返回True
而不返回0
df.groupby('pid').total_sum.transform(lambda x: x.diff().ne(0))
Out[121]:
0 True
1 True
2 True
3 True
4 True
5 False
6 True
7 True
8 True
9 False
Name: total_sum, dtype: bool
_ cumsum
是连续累加每行的累加和。在Python中,True
被解释为1
,而False
被解释为0
。每个组的第一个始终为True
,因此cumsum
总是从1
开始并将每行加起来以获得所需的输出。
df.groupby('pid').total_sum.transform(lambda x: x.diff().ne(0).cumsum())
Out[122]:
0 1
1 2
2 1
3 2
4 3
5 3
6 4
7 1
8 2
9 2
Name: total_sum, dtype: int32
将所有命令绑定到一个代码行,如下所示:
df['pos'] = df.groupby('pid').total_sum.transform(lambda x: x.diff().ne(0).cumsum())
Out[99]:
total_sum pid pos
0 5 2 1
1 1 2 2
2 6 7 1
3 3 7 2
4 1 7 3
5 1 7 3
6 0 7 4
7 5 10 1
8 1 10 2
9 1 10 2