如何根据2组列之间的值组合创建列?

我有一个逗号分隔值的数据框,我使用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
点赞