我遇到了熊猫问题。
我有一个如下数据框:
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
列的最有效方法的技巧都将受到高度赞赏。
请注意,日期始终是每月的第一天,这使计算变得更加容易。
答案 0 :(得分:1)
由GroupBy.diff
使用divide
和1 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)