在新的DataFrame列中计算自给定日期以来的月数

时间:2019-08-18 11:40:41

标签: python pandas datetime

我遇到了熊猫问题。

我有一个如下数据框:

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,其中包含给定名称的date列中第一个值之间的月数。这是为了计算自从名称第一次出现在DataFrame中以来已经过去了多少个月。计算必须按名称分组,因为我只想知道自从用户第一次出现在用户名出现的行中以来的月数,而不是其他任何用户名。

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

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

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

3 个答案:

答案 0 :(得分:2)

我们可以使用#include <iostream> class FooBar { public: virtual void foo() { std::cout << "foo" << std::endl; }; virtual void bar() { std::cout << "bar" << std::endl; }; }; int main() { FooBar obj; // first bytes of 'obj' is a pointer to vtable uintptr_t vtable_ptr = ((uintptr_t*)&obj)[0]; // 'foo' is at index '0' and 'bar' is at index '1' uintptr_t method_ptr = ((uintptr_t*)vtable_ptr)[1]; // cast it to member pointer void (*func)(FooBar*) = (void (*)(FooBar*))method_ptr; // invoke the member function on 'obj' (*func)(&obj); return 0; } 来获得与数据帧等长向量的最小值。然后用此向量减去每个GroupBy.transform值,然后将其除以date

1 month timedelta

输出

mins = df.groupby('name')['date'].transform('min')

df['months'] = df['date'].sub(mins).div(pd.Timedelta(1, 'M')).round().astype(int)

答案 1 :(得分:1)

您可以使用dateutil包。顺便说一句,根据您的逻辑,应该将第4行的月份改为3而不是2?

from dateutil.relativedelta import relativedelta

df['month'] = df.apply(lambda x: relativedelta(x.date,df.loc[df.name==x['name']].date.min()).months, axis=1)

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

答案 2 :(得分:0)

数据

df = pd.DataFrame({'name': ['Mark',
  'Anne',
  'Anne',
  'Anne',
  'Anne',
  'John',
  'John',
  'John',
  'Ethan'],
 'date': ['2018-01-01',
  '2018-01-01',
  '2018-02-01',
  '2018-04-01',
  '2018-09-01',
  '2018-02-01',
  '2018-06-01',
  '2018-08-01',
  '2018-03-01']}
)

要计算月份差异,我们可以将日期时间转换为期间('M'),期间差异具有名为n的属性,该属性返回数字

df.assign(date = lambda x:pd.to_datetime(x['date']).dt.to_period('M'),
          months = lambda x:x.groupby('name')['date'].apply(lambda x:x.sub(x.iloc[0])).apply(lambda x:x.n))