在数据帧上应用过滤器函数

凯尔·麦科姆

我有一个市场上的销售和采购数据集,看起来有点像这样。

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,则这意味着该用户同时存在SalePurchase另一方面,如果长度为 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附加到分组DataFramecross根据需要填充该

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章