如何计算Python数据帧中非连续行之间的差异?
我有以下数据框,并试图创建一个新的“Value_Diff”列,其中它计算当前“Value”(如果lable=0)与先前label=1的值之间的差异。如果label=1,则将“Value_Diff”设置为0。需要对每个组重复此过程,如果组中的第一个标签等于0,则应将“值_Diff”保持为0,直到其达到第一个标签=1,然后遵循相同的逻辑(本例中为C组) 我可以为每个组编写一个for循环和if语句来实现这一点,但是我想知道是否有更好的方法使用groupby、lambda或任何其他函数来实现这一点 以下是输入:如何计算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或任何其他函数来实现这一点 以下
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提到的,我在显示我的输出时犯了一个很快的错误,我将在我的帖子上更新输出,但是我将保留原始问题,因为我认为您的解决方案肯定会对这篇帖子有所帮助。