我有三个列表如下:
age = ['51+', '21-30', '41-50', '31-40', '<21']
cluster = ['notarget', 'cluster3', 'allclusters', 'cluster1', 'cluster2']
device = ['htc_one_2gb','iphone_6/6+_at&t','iphone_6/6+_vzn','iphone_6/6+_all_other_devices','htc_one_2gb_limited_time_offer','nokia_lumia_v3','iphone5s','htc_one_1gb','nokia_lumia_v3_more_everything']
我也有df中的列,如下所示:
campaign_name
0 notarget_<21_nokia_lumia_v3
1 htc_one_1gb_21-30_notarget
2 41-50_htc_one_2gb_cluster3
3 <21_htc_one_2gb_limited_time_offer_notarget
4 51+_cluster3_iphone_6/6+_all_other_devices
我想根据上面列表中的值将列拆分为三个单独的列。像这样:
age cluster device
0 <21 notarget nokia_lumia_v3
1 21-30 notarget htc_one_1gb
2 41-50 cluster3 htc_one_2gb
3 <21 notarget htc_one_2gb_limited_time_offer
4 51+ cluster3 iphone_6/6+_all_other_devices
首先想到的是做一个这样简单的测试:
ages_list = []
for i in ages:
if i in df['campaign_name'][0]:
ages_list.append(i)
print ages_list
>>> ['<21']
然后我将age_list转换为一个系列并将其与剩下的两个结合起来得到最终结果,但我假设有更多的pythonic方式呢?
答案 0 :(得分:2)
这背后的想法是你将根据你已经拥有的值创建一个正则表达式,例如,如果你想构建一个正则表达式来捕获你的年龄列表中的任何值,你可以做这样的事情{{ 1}}依此类推您已拥有的所有值'|'.join(age)
&amp; cluster
。
device
列表的特殊情况,因为它包含与正则表达式冲突的device
符号(因为+
表示正则表达式中的一个或多个)所以我们可以修复此问题将+
的任何值替换为+
的问题,这意味着我想按字面意思捕获\+
+
如果您想删除原始列,可以执行此操作
df = pd.DataFrame({'campaign_name' : ['notarget_<21_nokia_lumia_v3' , 'htc_one_1gb_21-30_notarget' , '41-50_htc_one_2gb_cluster3' , '<21_htc_one_2gb_limited_time_offer_notarget' , '51+_cluster3_iphone_6/6+_all_other_devices'] })
def split_df(df):
campaign_name = df['campaign_name']
df['age'] = re.findall('|'.join(age) , campaign_name)[0]
df['cluster'] = re.findall('|'.join(cluster) , campaign_name)[0]
df['device'] = re.findall('|'.join([x.replace('+' , '\+') for x in device ]) , campaign_name)[0]
return df
df.apply(split_df, axis = 1 )
这里我假设一个值必须与df.apply(split_df, axis = 1 ).drop( 'campaign_name', axis = 1)
匹配,但如果不是这种情况你可以进行检查,那么你就明白了