我有一个市场上的销售和采购数据集,看起来有点像这样。
User_ID | Transaction_Type | Date | Amount
1 | Sale | 01/01/14 | 200.00
2 | Purchase | 01/01/14 | 30.00
...
我需要过滤出只购买或出售某物的客户与至少购买和出售过一次某物的客户。
我正在尝试创建一个函数来检查用户是否已经完成了这两项操作。如果用户同时完成了这两项操作,则该用户将被标记为是,否则将被标记为否。
到目前为止,我已经尝试过这样做,
def user_filter(df):
if df in df['User_ID'].filter(lambda x : ((x['Transaction_Type']=='Sale').any())&((x['Transaction_Type']=='Purchase').any())):
return 'yes'
else:
return 'no'
df['cross'] = df['User_ID'].apply(user_filter)
让我们稍后在数据集中假设 User_ID 1 将作为购买返回。我希望它会返回为:
User_ID | Transaction_Type | Date | Amount | cross
1 | Sale | 01/01/14 | 200.00 | yes
2 | Purchase | 01/01/14 | 30.00 | no
但返回以下错误:
'int' object is not subscriptable
当我将它应用于整个数据帧而不是系列时,它返回:
KeyError: ('User_ID', 'occurred at index User_ID')
一种可能的方法是使用groupby
然后,而不是聚合,简单地列出Transaction_Type
每个组中的s,就像在这篇 SO 帖子中显示的那样。然后,只需获取列表的长度....如果长度为 2,则这意味着该用户同时存在Sale
和Purchase
。另一方面,如果长度为 1,则该用户只存在Sale
或 中的一个Purchase
。
根据 OP 生成一些数据(我添加了第三条记录以使输出更加明确)
d = [['User_ID', 'Transaction_Type', 'Date', 'Amount'],
[1, 'Sale', '01/01/14', 200],
[1, 'Purchase','01/02/14',300],
[2, 'Purchase','01/01/14',30],]
执行 GROUP BY
df_users = df.groupby('User_ID')['Transaction_Type'].apply(list).reset_index(drop=False)
df_users.rename(columns={'Transaction_Type':'Transactions'}, inplace=True)
print(df_users)
User_ID Transactions
0 1 [Sale, Purchase]
1 2 [Purchase]
现在将一cross
列附加到分组DataFrame
并cross
根据需要填充该列
df_users['cross'] = 'no'
df_users.loc[df_users.Transactions.apply(len)==2, 'cross'] = 'yes'
print(df_users)
User_ID Transactions cross
0 1 [Sale, Purchase] yes
1 2 [Purchase] no
编辑 1
或者,删除apply
步骤并使用size
df_users = df.groupby('User_ID')['Transaction_Type'].size().reset_index(drop=False)
df_users['cross'] = 'no'
df_users.loc[df_users.Transactions==2, 'cross'] = 'yes'
print(df_users)
User_ID Transactions cross
0 1 2 yes
1 2 1 no
编辑 2
如果您想将该cross
列附加到源代码DataFrame
,则将这两行代码添加到上面
df = df.merge(df_users, on='User_ID')
df.drop(columns=['Transactions'], inplace=True)
print(df)
User_ID Transaction_Type Date Amount cross
0 1 Sale 01/01/14 200 yes
1 1 Purchase 01/02/14 300 yes
2 2 Purchase 01/01/14 30 no
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句