如何避免遍历Pandas DataFrame,实现多列批量赋值?
高效处理Pandas DataFrame的条件赋值问题
原始数据与需求
数据初始化
import pandas as pd import numpy as np df = pd.DataFrame({ "col1": ["AA", "BB", np.nan, np.nan, "CC"], "col2": ["XYZ", "TEST", "123A", "JOHN", "DOE"], "col3": list(range(1,6)), "col4": [5, 4, 10, 2, 1], "col5": ["str1", "str2", np.nan, "str3", np.nan], "col6": ["test1", "t2", "t3", "t4", "t5"] })
需求说明
当col1单元格为空值时,执行以下赋值操作:
- 将
col2对应的值赋值给col1 - 将
col4对应的值赋值给col3 - 将
col6对应的值赋值给col5
低效的遍历实现
原代码通过循环逐行判断赋值,大数据量下效率极低:
for i in range(len(df)): if pd.isnull(df['col1'][i]): df['col1'][i] = df['col2'][i] df['col3'][i] = df['col4'][i] df['col5'][i] = df['col6'][i]
高效的Pandas风格实现方法
方法1:布尔索引 + .loc批量赋值
利用Pandas矢量化操作,直接定位符合条件的行批量完成多列赋值,这是处理此类场景的最优方案:
# 创建布尔掩码,筛选col1为空的行 mask = df['col1'].isna() # 批量赋值 df.loc[mask, 'col1'] = df.loc[mask, 'col2'] df.loc[mask, 'col3'] = df.loc[mask, 'col4'] df.loc[mask, 'col5'] = df.loc[mask, 'col6']
该方式完全规避Python层面的循环,所有操作在Pandas底层矢量化逻辑中执行,大数据量下效率提升显著。
方法2:结合combine_first与掩码判断
如果追求更简洁的写法,可针对空值替换场景用combine_first,非空值强制替换场景结合掩码判断:
mask = df['col1'].isna() df['col1'] = df['col1'].combine_first(df['col2']) df['col3'] = df['col3'].where(~mask, df['col4']) df['col5'] = df['col5'].combine_first(df['col6'])
验证结果
执行上述高效代码后,处理后的DataFrame如下:
col1 col2 col3 col4 col5 col6 0 AA XYZ 1 5 str1 test1 1 BB TEST 2 4 str2 t2 2 123A 123A 10 10 t3 t3 3 JOHN JOHN 2 2 t4 t4 4 CC DOE 5 1 str1 t5
内容的提问来源于stack exchange,提问作者szaki
相关产品推荐
相关产品推荐

