如何基于指定列表扩展/复制Pandas DataFrame行?
问题描述
现有如下结构的DataFrame:
col1 col2 col3 --- --- --- a1 b1 c1 a2 b2 c2 a3 b3 c3
以及列表 my_list = ['v1', 'v2', 'v3', 'v4'],希望生成每行与列表元素逐一组合、新增col4的扩展后DataFrame:
col1 col2 col3 col4 --- --- --- --- a1 b1 c1 v1 a1 b1 c1 v2 a1 b1 c1 v3 a1 b1 c1 v4 a2 b2 c2 v1 a2 b2 c2 v2 a2 b2 c2 v3 a2 b2 c2 v4 a3 b3 c3 v1 a3 b3 c3 v2 a3 b3 c3 v3 a3 b3 c3 v4
目前尝试用.melt函数实现,想知道有没有更优的解决思路。
更优解决思路
.melt其实不适合这个场景——它主要用来把宽表转成长表,而这里需要的是原DataFrame每行和列表元素做笛卡尔积,推荐两种更直接高效的方法:
方法1:用merge构造笛卡尔积
先把列表转成单独的DataFrame,再和原表做无关联条件的合并:
import pandas as pd # 原DataFrame df = pd.DataFrame({'col1': ['a1', 'a2', 'a3'], 'col2': ['b1', 'b2', 'b3'], 'col3': ['c1', 'c2', 'c3']}) my_list = ['v1', 'v2', 'v3', 'v4'] # 列表转成单列DataFrame df_list = pd.DataFrame({'col4': my_list}) # 笛卡尔积合并(Pandas 1.2.0+支持how='cross') result = df.merge(df_list, how='cross')
如果你的Pandas版本低于1.2.0,换这种写法:
result = df.assign(key=1).merge(df_list.assign(key=1), on='key').drop('key', axis=1)
逻辑直观,处理大数据量时效率也不错。
方法2:assign+explode快速实现
给原表新增一列,每一行的值都是整个列表,再用explode把列表拆成多行:
result = df.assign(col4=[my_list]*len(df)).explode('col4')
代码更简洁,适合小数据量场景,几步就能完成需求。
为啥不推荐用.melt?
用.melt的话得先给原表手动加v1、v2、v3、v4这几列,再转长,步骤繁琐还容易出错:
# 不推荐的melt写法 df_melt = df.assign(v1='v1', v2='v2', v3='v3', v4='v4').melt(id_vars=['col1','col2','col3'], value_name='col4').drop('variable', axis=1)
对比下来,前面两种方法不管是代码简洁度还是效率都更优。
内容的提问来源于stack exchange,提问作者hjsg1010
相关产品推荐
相关产品推荐

