基于Group匹配并按Repeat次数填充df1中Name列NaN值的高效方案
高效填充DataFrame中NaN值的解决方案
需求说明
现有两个DataFrame,需要通过Group字段匹配,用df2中的Name值填充df1中Name列的所有NaN,且需按照df2的Repeat指定次数重复填充,最终得到目标结果。
原始数据
import pandas as pd df1 = pd.DataFrame({'Group': ['xx', 'yy', 'zz', 'x', 'x', 'x','z','y','y','y','y'], 'Name': ['A', 'B', 'C', None, None, None, None, None, None, None, None], 'Value': [5, 3, 4, 7, 1, 3, 6, 5, 9, 5, 4]}) df2 = pd.DataFrame({'Name': ['A', 'A', 'B', 'B'], 'Group': ['x', 'y', 'z', 'y'], 'Repeat': [3, 2, 1, 2]})
期望输出
df = pd.DataFrame({'Group': ['xx', 'yy', 'zz', 'x', 'x', 'x','z','y','y','y','y'], 'Name': ['A', 'B', 'C', 'A', 'A', 'A', 'B', 'A', 'A', 'B', 'B'], 'Value': [5, 3, 4, 7, 1, 3, 6, 5, 9, 5, 4]})
原方案问题
你编写的嵌套循环代码效率极低,iterrows加上三层循环会大幅拖慢运行速度,尤其是数据量较大时,性能瓶颈会非常明显。
高效解决方案
利用pandas的矢量化操作实现,全程避免显式循环,代码简洁且性能优异:
import pandas as pd # 1. 将df2按Repeat次数扩展成对应行数的记录 df2_expanded = df2.loc[df2.index.repeat(df2['Repeat'])].reset_index(drop=True) # 2. 为扩展后的df2添加组内序号,用于后续匹配 df2_expanded['seq'] = df2_expanded.groupby('Group').cumcount() # 3. 筛选df1中需要填充的行,同样添加组内序号 mask = df1['Name'].isna() df1_fill = df1[mask].copy() df1_fill['seq'] = df1_fill.groupby('Group').cumcount() # 4. 通过Group和seq匹配,获取对应的Name值 filled = df1_fill.merge(df2_expanded[['Group', 'seq', 'Name']], on=['Group', 'seq'], how='left', suffixes=('_old', '')) # 5. 将填充后的Name更新回原df1 df1.loc[mask, 'Name'] = filled['Name'] # 查看结果 print(df1)
方案优势
- 全程使用pandas内部优化的矢量化操作,避免了Python层面的循环,运行效率比嵌套循环提升几个数量级
- 逻辑清晰,每一步操作都对应明确的目标,易于维护和扩展
内容的提问来源于stack exchange,提问作者parvez alam
相关产品推荐
相关产品推荐

