我遇到了熊猫问题。
我有一个如下数据框:
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
列的最有效方法的技巧都将受到高度赞赏。
答案 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))