我有一个如下所示的Pandas数据框,其中有两个任意的客户,他们有2个月的数据(还有更多的月份)和ATL_Flag,它们是营销渠道(也有更多的渠道):
|App_Flag|ATL_Flag|Cust_No|month1|month2
| 0 | TV | 1 | 1 | 0
| 0 | FB | 1 | 0 | 0
| 0 | OOH | 1 | 1 | 1
| 1 | RAD | 2 | 1 | 1
| 1 | TV | 2 | 1 | 0
| 1 | FB | 2 | 1 | 0
我的目标是构造ATL_Flags,使
1)其中,特定客户(群集/串联ATL_Flag)的月值为1。例如。在上面的示例中,对于month1和customer 1,字符串应为:TVOOH,对于month2和customer 1,字符串应为:OOH(month2向量仅具有单个1,对应于OOH)。
2)然后,将两个(或更多)个月的两个结果字符串组合在一起,如下所示:TVOOH-> OOH
最终结果应该是这样的:
|App_Flag|Cust_No|Path
| 0 | 1 | TVOOH->OOH |
| 1 | 2 | RADTVFB->RAD|
我用以下方法尝试过,但它似乎太慢且太复杂了:
def str_sum(channel):
return '>'.join(channel['c_path'])
wrk_data_temp = pd.melt(work_data_temp[['cust_no', 'ATL_Flag', 'max_exp_1_mnth', 'max_exp_2_mnth']], id_vars=['cust_no', 'ATL_Flag'], value_vars=['max_exp_1_mnth', 'max_exp_2_mnth'], value_name='key')
wrk_data_temp['variable'] = wrk_data_temp['variable'].str.extract(r'([\d]+)').astype(int)
wrk_data_temp['c_path'] = wrk_data_temp.sort_values(['cust_no', 'variable', 'ATL_Flag'])[wrk_data_temp.key == 1][['cust_no', 'ATL_Flag', 'variable']].groupby(['cust_no', 'variable']).transform('sum')
wrk_data_temp2 = wrk_data_temp[['cust_no', 'variable', 'c_path']].drop_duplicates()
wrk_data_temp3 = wrk_data_temp2.dropna()
final = pd.DataFrame(wrk_data_temp3[['cust_no', 'c_path']].groupby('cust_no').apply(str_sum))
答案 0 :(得分:2)
首先获取所有带有month
的列,将1
的值替换为ATL_Flag
列,然后按组汇总join
,然后再将其他join
的列合并在一起:
c = df.filter(like='month').columns
df[c] = np.where(df[c].astype(bool), df['ATL_Flag'].values[:, None], '')
df1 = (df.groupby(['App_Flag','Cust_No'])[c]
.agg(''.join)
.apply('>'.join, axis=1)
.reset_index(name='Path'))
print (df1)
App_Flag Cust_No Path
0 0 1 TVOOH>OOH
1 1 2 RADTVFB>RAD
编辑:忽略组中的0
值:
print (df)
App_Flag ATL_Flag Cust_No month1 month2 month3
0 0 TV 0 0 0 0
1 0 FB 1 0 0 0
2 0 OOH 1 0 1 1
3 1 RAD 2 1 1 0
4 1 TV 2 1 0 0
5 1 FB 3 1 0 1
c = df.filter(like='month').columns
df[c] = np.where(df[c].astype(bool), df['ATL_Flag'].values[:, None], '')
df1 = (df.groupby(['App_Flag','Cust_No'])[c]
.agg(''.join)
.apply(lambda x: '>'.join(y for y in x if y != ''), axis=1)
.reset_index(name='Path')
)
print (df1)
App_Flag Cust_No Path
0 0 0
1 0 1 OOH>OOH
2 1 2 RADTV>RAD
3 1 3 FB>FB