使用python pandas dataframe df:
product_id |transaction_id | category | color
234 54 A black
349 54 B silver
213 46 A silver
490 46 A black
245 87 A black
249 87 B black
294 87 A silver
我想标记具有相同颜色的A和B类别的transaction_ID。因此,在上面的场景中,交易87具有产品A黑色和产品B黑色。
期望的输出:
product_id |transaction_id | category | color | flag
234 54 A black
349 54 B silver
213 46 A silver
490 46 A black
245 87 A black X
249 87 B black X
294 87 A silver X
我试图在类别和颜色之间创建一个唯一的键,然后groupby,但它变得凌乱,我仍然需要手动完成它。必须有一个更简单的方法。
df['key']=df['category']&df['color']
df['transaction_analysis']= df.groupby('transaction_id').key.transform(lambda x : '&'.join(set(x)))
答案 0 :(得分:1)
不确定是否更简单,但肯定更清洁。您可以在simple_expr
= "x"
block_expr
= "x" sep block
expression
= simple_expr
/ block_expr
if_stmt
= "if" sep simple_expr sep block
和groupby
上transaction_id
,找到category
的唯一颜色,然后取消堆叠。
在此之后,生成标志值的映射并稍后分配给unique
。
df
v = (
df.groupby(['transaction_id', 'category'])
.color
.unique()
.unstack(fill_value=set())
)
m = {
k : 'X' if set(x).intersection(y) else '' for k, x, y in zip(v.index, v.A, v.B)
}
df['flag'] = df['transaction_id'].map(m)
答案 1 :(得分:1)
这是另一种方法:
import pandas as pd
df = pd.DataFrame({'category': ['A', 'B', 'A', 'A', 'A', 'B', 'A'],
'color': ['black', 'silver', 'silver', 'black',
'black', 'black', 'silver'],
'product_id': [234, 349, 213, 490, 245, 249, 294],
'transaction_id': [54, 54, 46, 46, 87, 87, 87]})
pivoted = df.pivot_table(index=['transaction_id','color'], columns=['category'],
values='product_id')
transaction_color_mask = pd.notnull(pivoted).all(axis=1)
transaction_map = transaction_color_mask.groupby(level=0).any().map({True:'X',False:''})
df['flag'] = df['transaction_id'].map(transaction_map)
print(df)
产量
category color product_id transaction_id flag
0 A black 234 54
1 B silver 349 54
2 A silver 213 46
3 A black 490 46
4 A black 245 87 X
5 B black 249 87 X
6 A silver 294 87 X
主要思想是使用pivot_table
公开要在行中进行比较的值:
In [182]: pivoted
Out[182]:
category A B
transaction_id color
46 black 490.0 NaN
silver 213.0 NaN
54 black 234.0 NaN
silver NaN 349.0
87 black 245.0 249.0
silver 294.0 NaN
现在我们可以找到类别A
和B
具有相同颜色的行:
In [183]: transaction_color_mask = pd.notnull(pivoted).all(axis=1); transaction_color_mask
Out[183]:
transaction_id color
46 black False
silver False
54 black False
silver False
87 black True
silver False
dtype: bool
按transaction_id
分组以查找与True行相关联的transaction_id
:
In [184]: transaction_color_mask.groupby(level=0).any()
Out[184]:
transaction_id
46 False
54 False
87 True
dtype: bool
然后将True
映射到'X'
和False
以清空字符串:
In [185]: transaction_color_mask.groupby(level=0).any().map({True:'X',False:''})
Out[185]:
transaction_id
46
54
87 X
dtype: object
最后,将结果与df
重新组合:df['flag'] = df['transaction_id'].map(transaction_map)
会产生所需的结果。