计算groupby DataFrame中连续行之间的日期时间差

时间:2019-08-19 11:33:18

标签: python pandas

我遇到了熊猫问题。

我有一个如下数据框:

name     date
Mark     2018-01-01
Anne     2018-01-01
Anne     2018-02-01
Anne     2018-04-01
Anne     2018-09-01
Anne     2019-01-01    
John     2018-02-01
John     2018-06-01
John     2019-02-01
Ethan    2018-03-01

我需要计算另外一列,称为months,其中包含相同名称的每个连续行之间的月数。这是为了计算名称的一个外观与DataFrame中的下一个外观之间相隔了多少个月。计算必须按名称分组,因为我只想知道一个用户(而不是不同名称)的连续出现之间的月份数。

在这种情况下,预期输出为:

name     date          months
Mark     2018-01-01    0
Anne     2018-01-01    0
Anne     2018-02-01    1
Anne     2018-04-01    2
Anne     2018-09-01    5
Anne     2019-01-01    4
John     2018-02-01    0
John     2018-06-01    4
John     2019-02-01    8
Ethan    2018-03-01    0

任何关于计算months列的最有效方法的技巧都将受到高度赞赏。

请注意,日期始终是每月的第一天,这使计算变得更加容易。

3 个答案:

答案 0 :(得分:1)

GroupBy.diff使用divide1 month timedelta

df['months'] = df.groupby('name')['date'].diff().div(pd.Timedelta(days=30.44), fill_value=0).round().astype(int)

输出

    name       date  months
0   Mark 2018-01-01       0
1   Anne 2018-01-01       0
2   Anne 2018-02-01       1
3   Anne 2018-04-01       2
4   Anne 2018-09-01       5
5   Anne 2019-01-01       4
6   John 2018-02-01       0
7   John 2018-06-01       4
8   John 2019-02-01       8
9  Ethan 2018-03-01       0

答案 1 :(得分:1)

将值转换为months,然后通过DataFrameGroupBy.diff得到差值:

df['date'] = pd.to_datetime(df['date'])

a = df['date'].dt.year * 12 + df['date'].dt.month - 1
df['months'] = a.groupby(df['name']).diff().fillna(0).astype(int)
print (df)
    name       date  months
0   Mark 2018-01-01       0
1   Anne 2018-01-01       0
2   Anne 2018-02-01       1
3   Anne 2018-04-01       2
4   Anne 2018-09-01       5
5   Anne 2019-01-01       4
6   John 2018-02-01       0
7   John 2018-06-01       4
8   John 2019-02-01       8
9  Ethan 2018-03-01       0

另一种解决方案:

df['date'] = pd.to_datetime(df['date'])

from operator import attrgetter
df['months'] = (df.assign(month = df['date'].dt.to_period('m'))
                  .groupby('name')['month']
                  .diff()
                  .dropna()
                  .apply(attrgetter('n'))
                  .reindex(df.index, fill_value=0))

print (df)
    name       date  months
0   Mark 2018-01-01       0
1   Anne 2018-01-01       0
2   Anne 2018-02-01       1
3   Anne 2018-04-01       2
4   Anne 2018-09-01       5
5   Anne 2019-01-01       4
6   John 2018-02-01       0
7   John 2018-06-01       4
8   John 2019-02-01       8
9  Ethan 2018-03-01       0

答案 2 :(得分:0)

从日期开始提取的第一个月

df.date  = pd.to_datetime(df.date)
df['Month_from_date'] = pd.DatetimeIndex(df['date']).month

然后计算差异

df['months'] = df['Month_from_date'] - df['Month_from_date'].shift(1)