应用Pandas数据帧引用前一行以计算差异

2024-06-25 23:12:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下包含两列的pandas数据框(简化版)。第一列包含播放器名,第二列包含日期datetime对象):

  player    date
  A         2010-01-01
  A         2010-01-09
  A         2010-01-11
  A         2010-01-15
  B         2010-02-01
  B         2010-02-10
  B         2010-02-21
  B         2010-02-23

我想添加一列diff表示每个玩家的时间差。结果应该是这样的:

  player    date            diff
  A         2010-01-01      0
  A         2010-01-09      8
  A         2010-01-11      2
  A         2010-01-15      4
  B         2010-02-01      0
  B         2010-02-10      9
  B         2010-02-21      11
  B         2010-02-23      2

第一行有diff的0,因为没有更早的日期。第二行显示8,因为2010-01-012010-01-09之间的差异是8天。

问题不在于计算两个datetime对象之间的日差。我只是不知道如何添加新列。我知道,我必须先做一个groupbydf.groupby('player')),然后使用apply(或者transform?)。然而,我陷入了困境,因为为了计算差异,我需要引用apply函数中的前一行,如果可能的话,我根本不知道如何做到这一点。

非常感谢。

更新: 在尝试了下面两个建议的解决方案之后,我发现它们不适用于我的代码。头痛了很久,我发现我的数据有重复的索引。所以在我发现我有重复的索引之后,一个简单的df.reset_index()解决了我的问题,并且提出的解决方案奏效了。由于这两个解决方案都有效,但我只能将其中一个标记为正确,所以我将选择更简洁/更短的解决方案。不过,还是要感谢你们两位!


Tags: 数据对象pandasdfdatetimedate玩家diff
3条回答

你可以简单地写下:

df['difference'] = df.groupby('player')['date'].diff().fillna(0)

这将为新的timedelta列提供正确的值:

  player       date  difference
0      A 2010-01-01      0 days
1      A 2010-01-09      8 days
2      A 2010-01-11      2 days
3      A 2010-01-15      4 days
4      B 2010-02-01      0 days
5      B 2010-02-10      9 days
6      B 2010-02-21     11 days
7      B 2010-02-23      2 days

(我使用了名称“difference”而不是“diff”来区分名称和方法diff

shift()是一个很好的函数,但是,如果需要避免数据重复,我建议使用以下方法。

def date_diff(row):
    index = df.index.get_loc(row.name)
    if index == 0:
        return np.nan
    prev_row = df.iloc[index - 1]
    return row['date'] - prev_row['date']

df['difference'] = df.apply(date_diff, axis=1)

如果要手动实现它,另一种方法是执行以下操作

def date_diff(df):
    df['difference'] = df['date'] - df['date'].shift()
    df['difference'].fillna(0 ,inplace = True)
    return df

In [30]:
df_final = df.groupby(df['player']).apply(date_diff)
df_final
Out[30]:
player  date    difference
A   2010-01-01  0 days
A   2010-01-09  8 days
A   2010-01-11  2 days
A   2010-01-15  4 days
B   2010-02-01  0 days
B   2010-02-10  9 days
B   2010-02-21  11 days
B   2010-02-23  2 days

相关问题 更多 >