如何用更Pythonic的方式复制Pandas数据行并追加ID后缀
问题描述
需要复制Pandas DataFrame中的每一行,在id列末尾添加指定字符串(如_dup1、_dup2),同时保持其他列数据不变。
初始数据:
import pandas as pd I_have = pd.DataFrame({'id':['a','b','c'], 'my_data':[1,2,3]})
期望输出:
id my_data a 1 a_dup1 1 a_dup2 1 b 2 b_dup1 2 b_dup2 2 c 3 c_dup1 3 c_dup2 3
现有可行代码通过多次复制拼接实现,但希望找到更Pythonic的方案:
tmp1 = I_have.copy(deep=True) tmp2 = I_have.copy(deep=True) tmp1['id'] = tmp1['id']+'_dup1' tmp2['id'] = tmp2['id']+'_dup2' pd.concat([I_have, tmp1, tmp2])
更优实现方案
方案1:列表推导式 + concat + assign
这是最简洁且易扩展的写法,直接通过列表推导式生成所有后缀对应的DataFrame,再一次性拼接:
import pandas as pd I_have = pd.DataFrame({'id':['a','b','c'], 'my_data':[1,2,3]}) suffixes = ['', '_dup1', '_dup2'] result = pd.concat( [I_have.assign(id=I_have['id'] + suffix) for suffix in suffixes], ignore_index=True )
优势:
- 代码紧凑,避免重复的变量定义
- 扩展性极强:新增后缀(如
_dup3)只需在suffixes列表中添加元素,无需修改其他代码 - 完全利用Pandas的向量化操作,效率高于循环类方法
方案2:交叉合并(merge cross)
通过生成后缀辅助表,和原数据交叉合并后拼接id,适合需要明确生成所有组合的场景:
import pandas as pd I_have = pd.DataFrame({'id':['a','b','c'], 'my_data':[1,2,3]}) suffixes = ['', '_dup1', '_dup2'] # 生成后缀辅助DataFrame suffix_df = pd.DataFrame({'suffix': suffixes}) # 交叉合并得到所有行+后缀的组合 merged = I_have.merge(suffix_df, how='cross') # 拼接id和后缀,移除临时列 merged['id'] = merged['id'] + merged['suffix'] result = merged.drop('suffix', axis=1).sort_values('id').reset_index(drop=True)
优势:
- 逻辑清晰,直观展示行与后缀的组合关系
- 同样支持灵活扩展后缀列表
方案3:重复行 + 分组添加后缀
利用repeat重复行后,通过分组累计计数匹配后缀:
import pandas as pd I_have = pd.DataFrame({'id':['a','b','c'], 'my_data':[1,2,3]}) suffix_map = {0:'', 1:'_dup1', 2:'_dup2'} # 每个行重复对应次数 repeated_df = I_have.loc[I_have.index.repeat(len(suffix_map))].reset_index(drop=True) # 分组后根据累计计数匹配后缀 repeated_df['id'] = repeated_df['id'] + repeated_df.groupby('id').cumcount().map(suffix_map)
优势:
- 无需额外生成辅助表,直接在原数据基础上扩展
内容的提问来源于stack exchange,提问作者pinegulf
相关产品推荐
相关产品推荐

