我对如何在python pandas中完成此操作有点困惑;可能有一个更简单的解决方案,我无法在stackoverflow或谷歌上找到。
我有以下数据框df:
Customer_ID | date | year | Dollars
ABC 2017-02-07 2017 456
ABC 2017-03-05 2017 167
ABC 2016-12-13 2016 320
ABC 2015-04-07 2015 145
BCD 2017-09-08 2017 155
BCD 2016-10-22 2016 274
BCD 2016-10-19 2016 255
这是一个简单的数据框,但非常大。对于每个客户,我都有他们交易的日期和他们花了多少钱。我为分析创建了年份列。
#ensured data is in date format
df['date']=pd.to_datetime(df['date'], format='%Y-%m-%d')
#year of transaction as per comment from @Andrew L
df['year'] = df['date'].dt.year
我想做以下事情:
所以我正在寻找这个输出:
Customer_ID| date | year | Dollars |visit# |17visit#| 16visit# | 15visit#
ABC 2017-02-07 2017 456 3 1 0 0
ABC 2017-03-05 2017 167 4 2 0 0
ABC 2016-12-13 2016 320 2 0 1 0
ABC 2015-04-07 2015 145 1 0 0 1
BCD 2017-09-08 2017 155 3 1 0 0
BCD 2016-10-22 2016 274 2 0 2 0
BCD 2016-10-19 2016 255 1 0 1 0
我不知道从哪里开始,它会不会像groupby那样计算并计算日期?
任何想法或建议都将不胜感激。谢谢
答案 0 :(得分:1)
使用您的数据:
df
Customer_ID date year Dollars
0 ABC 2017-02-07 2017 456
1 ABC 2017-03-05 2017 167
2 ABC 2016-12-13 2016 320
3 ABC 2015-04-07 2015 145
4 BCD 2017-09-08 2017 155
5 BCD 2016-10-22 2016 274
6 BCD 2016-10-19 2016 255
按年度查找每位客户的累计访问次数:
df['visit_yr'] = df.groupby(['Customer_ID', 'year']).cumcount()+1
我们现在有" visit_yr" - 每年访问次数:
df
Customer_ID date year Dollars visit_yr
0 ABC 2017-02-07 2017 456 1
1 ABC 2017-03-05 2017 167 2
2 ABC 2016-12-13 2016 320 1
3 ABC 2015-04-07 2015 145 1
4 BCD 2017-09-08 2017 155 1
5 BCD 2016-10-22 2016 274 1
6 BCD 2016-10-19 2016 255 2
使用此功能,我们可以将年份转换为列(最后两位数),同时将NaN
替换为0'然后加入df
:
df.join(df.assign(yr_2 =df.year.astype(str).str[2:]+'visit').pivot(columns='yr_2', values='visit_yr').replace(np.nan, 0.0)).drop('visit_yr', axis=1)
Customer_ID date year Dollars visit_yr 15visit 16visit 17visit
0 ABC 2017-02-07 2017 456 1 0.0 0.0 1.0
1 ABC 2017-03-05 2017 167 2 0.0 0.0 2.0
2 ABC 2016-12-13 2016 320 1 0.0 1.0 0.0
3 ABC 2015-04-07 2015 145 1 1.0 0.0 0.0
4 BCD 2017-09-08 2017 155 1 0.0 0.0 1.0
5 BCD 2016-10-22 2016 274 1 0.0 1.0 0.0
6 BCD 2016-10-19 2016 255 2 0.0 2.0 0.0
访问整个数据集的计数:
df['visit'] = df.groupby('Customer_ID').cumcount()+1