Pandas数据帧应用参考前一行来计算差异

时间:2015-11-01 10:16:44

标签: python pandas dataframe apply

我有以下pandas数据帧包含2列(简化)。第一列包含播放器名称,第二列包含日期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之间的差异为八天。

问题不在于计算两个datetime个对象之间的日差。我只是不确定如何添加新列。我知道,我必须首先groupbydf.groupby('player')),然后使用apply(或者transform?)。但是,我被卡住了,因为为了计算差异,我需要在apply-function中引用上一行,如果可能的话,我不知道如何做到这一点。< / p>

非常感谢。

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

3 个答案:

答案 0 :(得分:4)

您可以简单地写一下:

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

(我使用名称“差异”代替“差异”来区分名称与方法diff。)

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

var webClient = new WebClient(); var result = webClient.DownloadData(url); var contentType = webClient.ResponseHeaders["Content-Type"]; if (contentType != null && contentType.StartsWith("image", StringComparison.OrdinalIgnoreCase)) { // it's probably an image } 是一个很好的功能,但是,如果您需要避免重复数据,我建议您使用以下方法。

shift()