Pandas 计算一组中的所有值与上一组的最后一个值之间的差异

use*_*022 1 python dataframe pandas

说我有一个熊猫数据框如下

df = pd.DataFrame({'val': [30, 40, 50, 60, 70, 80, 90], 'idx': [9, 8, 7, 6, 5, 4, 3],
                     'category': ['a', 'a', 'b', 'b', 'c', 'c', 'c']}).set_index('idx')

Ouput:

      val category
idx              
9     30        a
8     40        a
7     50        b
6     60        b
5     70        c
4     80        c
3     90        c
Run Code Online (Sandbox Code Playgroud)

我想添加一个新列,其中每个 'val' 和上一个类别的最后一个 'val' 之间存在差异。新列应如下所示:

     category    diff  val
idx                       
9          a     nan     30
8          a     nan     40
7          b      10     50
6          b      20     60
5          c      10     70
4          c      20     80
3          c      30     90
Run Code Online (Sandbox Code Playgroud)

目前我做这样的事情:

temp_df = df.groupby('category')['val'].agg('last').rename('lastVal').shift()
df = df.merge(temp_df, on='date', how='outer', right_index=True)
df['diff'] = df['val'] - df['lastVal']
Run Code Online (Sandbox Code Playgroud)

然而,它很慢。有一个更好的方法吗?

cs9*_*s95 5

您可以通过首先将 category 设置为索引来将映射卸载到 Pandas:

df2 = df.set_index('category')
df['diff'] = (
    df2['val'] - df.groupby('category')['val'].last().shift()).to_numpy()

df

     val category  diff
idx                    
9     30        a   NaN
8     40        a   NaN
7     50        b  10.0
6     60        b  20.0
5     70        c  10.0
4     80        c  20.0
3     90        c  30.0
Run Code Online (Sandbox Code Playgroud)