Pandas 计算行间差异

Pandas calculating difference between rows

我的目标是计算从 Start/End 到 End 的天差。我知道我必须按 Id 对它们进行分组,但我不确定如何执行 Day 之间的差异。

我试过 df['length'] = -(df.groupby('Id')['Day'].diff())。这与 End 没有比较,它仅在 Status 更改时计算差异。

df

Id Day Status

111 1 Start

111 5 End

222 2 Begin

222 7 End

333 1 Start

333 3 Begin

333 7 End

理想的结果是:

Id Day Status Length

111 1 Start 4

111 5 End 

222 2 Begin 5

222 7 End

333 1 Start 6 (since we Start on Day 1 and End on day 7)

333 3 Begin 4 (since we Begin on Day 3 and End on day 7)

333 7 End

谢谢

通过使用 apply.iloc

df.groupby('Id').Day.apply(lambda x : x.iloc[-1]-x).replace(0,np.nan)
Out[187]: 
0    4.0
1    NaN
2    5.0
3    NaN
4    6.0
5    4.0
6    NaN
Name: Day, dtype: float64

分配回来后

df['Length']=df.groupby('Id').Day.apply(lambda x : x.iloc[-1]-x).replace(0,np.nan)
df
Out[189]: 
    Id  Day Status  Length
0  111    1  Start     4.0
1  111    5    End     NaN
2  222    2  Begin     5.0
3  222    7    End     NaN
4  333    1  Start     6.0
5  333    3  Begin     4.0
6  333    7    End     NaN

这是另一种方法 groupby + transform -

v = df.groupby('Id').Day.transform('last') - df.Day
df['Length'] = v.mask(v == 0)  # or v.mask(df.Status.eq('End'))

df

    Id  Day Status  Length
0  111    1  Start     4.0
1  111    5    End     NaN
2  222    2  Begin     5.0
3  222    7    End     NaN
4  333    1  Start     6.0
5  333    3  Begin     4.0
6  333    7    End     NaN

计时

df = pd.concat([df] * 1000000, ignore_index=True)

# apply + iloc
%timeit df.groupby('Id').Day.apply(lambda x : x.iloc[-1]-x).replace(0,np.nan)
1 loop, best of 3: 1.49 s per loop

# transform + mask 
%%timeit
v = df.groupby('Id').Day.transform('last') - df.Day
df['Length'] = v.mask(v == 0)

1 loop, best of 3: 294 ms per loop