Python 熊猫:在熊猫中复制excel公式

Python 熊猫:在熊猫中复制excel公式,python,pandas,dataframe,sorting,Python,Pandas,Dataframe,Sorting,我拥有的是一个数据帧,如: 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

我拥有的是一个数据帧,如:

   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
背后的逻辑是:

pid
的初始
pos
值为
1

如果
pid
没有改变,但
总和
改变,则
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 )))

说明

pid
上执行
groupby
,将相同的
pid
分组为不同的组。在每个组上,应用以下操作:

_对每组调用
diff
diff
返回整数或
NaN
指示两个连续行之间的差异。每个组的第一行没有前一行,因此对于每个组的第一行,
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
。它在非
0
0时返回
True

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

第5行和第6行是否应该具有相同的
pos
值?已修复,抱歉,。为了完成这件事,我一直在发疯。因此粘贴了一个轻微的键入结果。
cumsum()在做什么?你能解释一下吗?我想理解它,而不是仅仅去做它,给我几分钟:)@LeeKan:我补充了一步一步的解释。
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