如何计算Python数据帧中非连续行之间的差异?

如何计算Python数据帧中非连续行之间的差异?,python,pandas,dataframe,Python,Pandas,Dataframe,我有以下数据框,并试图创建一个新的“Value_Diff”列,其中它计算当前“Value”(如果lable=0)与先前label=1的值之间的差异。如果label=1,则将“Value_Diff”设置为0。需要对每个组重复此过程,如果组中的第一个标签等于0,则应将“值_Diff”保持为0,直到其达到第一个标签=1,然后遵循相同的逻辑(本例中为C组) 我可以为每个组编写一个for循环和if语句来实现这一点,但是我想知道是否有更好的方法使用groupby、lambda或任何其他函数来实现这一点 以下

我有以下数据框,并试图创建一个新的“Value_Diff”列,其中它计算当前“Value”(如果lable=0)与先前label=1的值之间的差异。如果label=1,则将“Value_Diff”设置为0。需要对每个组重复此过程,如果组中的第一个标签等于0,则应将“值_Diff”保持为0,直到其达到第一个标签=1,然后遵循相同的逻辑(本例中为C组)

我可以为每个组编写一个for循环和if语句来实现这一点,但是我想知道是否有更好的方法使用groupby、lambda或任何其他函数来实现这一点

以下是输入:

 group  Date         Value   label   
 A     2020-03-01   -117    1           
 A     2020-03-02   -121    0             
 A     2020-03-03   -122    0           
 A     2020-03-04   -122    1           
 B     2020-03-05   -118    1           
 B     2020-03-06   -122    0           
 B     2020-03-07   -124    0           
 B     2020-03-08   -126    0           
 B     2020-03-09   -126    1           
 C     2020-03-10   -130    0           
 C     2020-03-11   -140    0           
 C     2020-03-12   -150    1           
 C     2020-03-13   -160    0           
答案应该是这样的:

 group  Date        Value  label   Value_Diff
 A     2020-03-01   -117    1         0
 A     2020-03-02   -121    0         4 (-117-(-121)=4)
 A     2020-03-03   -122    0         1
 A     2020-03-04   -122    1         0
 B     2020-03-05   -118    1         0
 B     2020-03-06   -122    0         4
 B     2020-03-07   -124    0         2
 B     2020-03-08   -126    0         2
 B     2020-03-09   -126    1         0
 C     2020-03-10   -130    0         0
 C     2020-03-11   -140    0         0  
 C     2020-03-12   -150    1         0  
 C     2020-03-13   -160    0         10
很抱歉,我的第一个输出实际上没有反映出我想要的内容,因为@BENY提供了这个输出的解决方案,我将把它留在这里,以帮助其他人解决同样的问题。 下面是实际输出的样子

 group  Date        Value  label   Value_Diff
 A     2020-03-01   -117    1         0
 A     2020-03-02   -121    0         4 (-117-(-121)=4)
 A     2020-03-03   -122    0         5 (-117-(-122)=5)
 A     2020-03-04   -122    1         0
 B     2020-03-05   -118    1         0
 B     2020-03-06   -122    0         4 (-122-(-118)=4)
 B     2020-03-07   -124    0         6 (-124-(-118)=6)
 B     2020-03-08   -126    0         8 (-126-(-118)=8)
 B     2020-03-09   -126    1         0
 C     2020-03-10   -130    0         0
 C     2020-03-11   -140    0         0  
 C     2020-03-12   -150    1         0  
 C     2020-03-13   -160    0         10 (-150-(-160)=10)

我们可以尝试使用
cummax
创建第一个条件,然后使用
groupby
diff

s = df.groupby('group').label.cummax()
df['new'] = -df.groupby('group').Value.diff().fillna(0).where(s==1 & df.label.ne(1),0)
df
Out[135]: 
   group        Date  Value  label   new
0      A  2020-03-01   -117      1  -0.0
1      A  2020-03-02   -121      0   4.0
2      A  2020-03-03   -122      0   1.0
3      A  2020-03-04   -122      1  -0.0
4      B  2020-03-05   -118      1  -0.0
5      B  2020-03-06   -122      0   4.0
6      B  2020-03-07   -124      0   2.0
7      B  2020-03-08   -126      0   2.0
8      B  2020-03-09   -126      1  -0.0
9      C  2020-03-10   -130      0  -0.0
10     C  2020-03-11   -140      0  -0.0
11     C  2020-03-12   -150      1  -0.0
12     C  2020-03-13   -160      0  10.0

我发现最好一步一步地做这些事情。我认为这是你想要的(第二个版本):

df['Value_Last'] = np.nan
df.loc[df.label == 1, 'Value_Last'] = df.loc[df.label == 1, 'Value']
df_grouped = df.groupby('group')
df['Value_Last'] = df_grouped['Value_Last'].ffill()
df['Value_Diff'] = (df['Value_Last'] - df['Value']).fillna(0)


   group        Date  Value  label  Value_Last  Value_Diff
0      A  2020-03-01   -117      1      -117.0         0.0
1      A  2020-03-02   -121      0      -117.0         4.0
2      A  2020-03-03   -122      0      -117.0         5.0
3      A  2020-03-04   -122      1      -122.0         0.0
4      B  2020-03-05   -118      1      -118.0         0.0
5      B  2020-03-06   -122      0      -118.0         4.0
6      B  2020-03-07   -124      0      -118.0         6.0
7      B  2020-03-08   -126      0      -118.0         8.0
8      B  2020-03-09   -126      1      -126.0         0.0
9      C  2020-03-10   -130      0         NaN         0.0
10     C  2020-03-11   -140      0         NaN         0.0
11     C  2020-03-12   -150      1      -150.0         0.0
12     C  2020-03-13   -160      0      -150.0        10.0

PS:如果
'Value'
列只包含整数,那么您可以使用最后一行末尾的
.astype(int)
'Value\u Diff'
转换回整数。

为什么您的第三行的值Diff为1?@nms:非常感谢,您是正确的,我忘了调整参考值以匹配我的问题陈述,它实际上应该是5,(-117-122=5),我将编辑我的帖子以复制它。这是一个相当复杂的操作。最终目标是什么?“价值差异”的用途是什么?我这样问是因为也许有更好的方法来实现你最终想要做的事情。是的,我想这会很复杂。这就是库存/供应问题。暂时忽略负数。该值应表示商店中的库存,标签是客户重新填充其库存时的标识符。我正在尝试获取客户每次重新填充其库存时之间的库存差异(“Value_Diff”列)。感谢Beny,我以前没有使用cummax和“.ne”,所以我肯定学会了这些技巧。我只在pyspark中使用“.where”,现在我知道我可以在熊猫中使用它。正如@nms提到的,我在显示我的输出时犯了一个很快的错误,我将在我的帖子上更新输出,但是我将保留原始问题,因为我认为您的解决方案肯定会对这篇帖子有所帮助。