考虑以下简化的示例数据帧df
:
Department CustomerID Date Price MenswearDemand HomeDemand
0 Menswear 418089 2019-04-18 199 199 0
1 Menswear 613573 2019-04-24 199 199 0
2 Menswear 161840 2019-04-25 199 199 0
3 Menswear 2134926 2019-04-29 199 199 0
4 Menswear 984801 2019-04-30 19 19 0
5 Home 398555 2019-01-27 52 0 52
6 Menswear 682906 2019-02-03 97 97 0
7 Menswear 682906 2019-02-03 97 97 0
8 Menswear 923491 2019-02-09 80 80 0
9 Menswear 1098782 2019-02-25 258 258 0
10 Menswear 721696 2019-03-25 12 12 0
11 Menswear 695706 2019-04-10 129 129 0
12 Underwear 637026 2019-01-18 349 0 0
13 Underwear 205997 2019-01-25 279 0 0
14 Underwear 787984 2019-02-01 27 0 0
15 Underwear 318256 2019-02-01 279 0 0
16 Underwear 570454 2019-02-14 262 0 0
17 Underwear 1239118 2019-02-28 279 0 0
18 Home 1680791 2019-04-04 1398 0 1398
我想根据以下内容对这些数据进行分组'CustomerID'
进而:
- 转动购买日期
'Date'
到截止日期之前的天数,即'2021-01-01'
。这只是客户最近一次购买到的时间'2021-01-01'
.
- 对所有剩余的需求列求和,仅在本示例中
'MenswearDemand'
and 'HomeDemand'
.
我应该得到的结果是这样的:
Date MenswearDemand HomeDemand
CustomerID
161840 6 199 0
205997 96 0 0
318256 89 0 0
398555 94 0 52
418089 13 199 0
570454 76 0 0
613573 7 199 0
637026 103 0 0
682906 87 194 0
695706 21 129 0
721696 37 12 0
787984 89 0 0
923491 81 80 0
984801 1 19 0
1098782 65 258 0
1239118 62 0 0
1680791 27 0 1398
2134926 2 199 0
这就是我设法解决这个问题的方法:
df['Date'] = pd.to_datetime(df['Date'])
cutoffDate = df['Date'].max() + dt.timedelta(days = 1)
newdf = df.groupby('CustomerID').agg({'Date': lambda x: (cutoffDate - x.max()).days,
'MenswearDemand': lambda x: x.sum(),
'HomeDemand': lambda x: x.sum()})
然而,实际上我得到了大约 1500 万行和 30 个需求列。我真的不想写所有这些'DemandColumn': lambda x: x.sum()
每次都在我的聚合函数中,因为它们都应该被求和。有更好的方法吗?就像传入一个想要执行特定操作的列子集数组一样?
如果您提前知道列名称,则可以在传递到之前构建字典agg
功能。
...
cutoffDate = df['Date'].max() + dt.timedelta(days=1)
agg_dict = {'Date': lambda x: (cutoffDate - x.max()).days}
DemandColumns = ['MenswearDemand', 'HomeDemand']
f = lambda x: x.sum()
agg_dict.update({col_name: f for col_name in DemandColumns})
newdf = df.groupby('CustomerID').agg(agg_dict)
另一种选择(知道列名,DemandColumns
在前面的示例中)是首先使用agg
函数来计算Date
列,然后使用filter https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.filter.html函数传递所需列的列表作为items
参数仅保留那些确切的列。
...
cutoffDate = df['Date'].max() + dt.timedelta(days=1)
groups = df.groupby('CustomerID')
newdf = groups.agg(lambda x: (cutoffDate - x.max()).days)
newdf = pd.concat([newdf, groups.apply(lambda x: x.filter(items=DemandColumns).agg(sum))], axis=1)
如果所需的列(DemandColumns
)遵循给定的模式,您可以排除列表创建并使用filter
函数与regex
争论。在这种情况下,您可以使用正则表达式'.*Demand$'
返回以 结尾的所有列Demand
string.
newdf = pd.concat([newdf, groups.apply(lambda x: x.filter(regex='.*Demand$').agg(sum))], axis=1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)