我有一个逗号分隔值的数据框,我使用pd.concat拆分出来.
原始df:
org country type
Orange USA, GBR, AUS OWF, PMR, KIQ
Red AUS, RUS, NZL DOG, MOP, LOF
拆分列给了我一个df,我们称之为df_wide,
org country_1 country_2 country_3 type_1 type_2 type_3
Orange USA GBR AUS OWF PMR KIQ
Watermelon AUS RUS NZL ODG MOP LOF
从上面的数据框架中,我需要以长格式获得单个国家/地区和单一类型的所有可能组合:
org country type
Orange USA OWF
Orange USA PMR
Orange USA KIQ
Orange GBR OWF
Orange GBR PMR
Orange GBR KIQ
……等等
这就是我被困住的地方.我错误地认为我可以使用pd.wide_to_long转换数据帧,但我认为我的回答是围绕使用itertools.我搜索了与此问题相关的论坛,但我还是没有完全弄明白.寻找任何建议!原始df列中逗号分隔的值也可能是几十个值,因此我不知道我的宽df会有多少列.
解决方法:
这是使用itertools.product的一个解决方案.它不需要您创建的中间数据帧.
from itertools import chain, product
df = pd.DataFrame({'org': ['Orange', 'Red'],
'country': ['USA, GBR, AUS', 'AUS, RUS, NZL'],
'type': ['OWF, PMR, KIQ', 'DOG, MOP, LOF']})
split1 = df['country'].str.split(', ')
split2 = df['type'].str.split(', ')
lens = split1.map(len) * split2.map(len)
c_list, t_list = zip(*chain.from_iterable(map(product, split1, split2)))
res = pd.DataFrame({'org': np.repeat(df['org'], lens),
'country': c_list,
'type': t_list})
说明
神奇的是这条线:
c_list, t_list = zip(*chain.from_iterable(map(product, split1, split2)))
从内到外工作:
>通过split1 / split2计算每对项目的笛卡尔积.
>将它们链接在一起成为非嵌套的可迭代结果.
>打开包装并压缩成国家和类型.
结果
print(res)
org country type
0 Orange USA OWF
0 Orange USA PMR
0 Orange USA KIQ
0 Orange GBR OWF
0 Orange GBR PMR
0 Orange GBR KIQ
0 Orange AUS OWF
0 Orange AUS PMR
0 Orange AUS KIQ
1 Red AUS DOG
1 Red AUS MOP
1 Red AUS LOF
1 Red RUS DOG
1 Red RUS MOP
1 Red RUS LOF
1 Red NZL DOG
1 Red NZL MOP
1 Red NZL LOF