pandas按多列非空优先级生成新列?df.apply与np.select实现对比
逐行df.apply实现方法
首先导入依赖、构建测试DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame.from_dict({ 'master_feature': ['ab', float('NaN'), float('NaN')], 'feature': [float('NaN'), float('NaN'), 'pq'], 'epic': [float('NaN'), 'fg', float('NaN')] })
实现逻辑非常直接:编写自定义逐行判断函数,按指定优先级依次检查三列的非空状态,匹配对应返回值,最后通过apply逐行应用生成promoted列:
def get_promoted_type(row): # 按优先级从高到低校验非空 if pd.notna(row['master_feature']): return 'master feature' elif pd.notna(row['feature']): return 'feature' elif pd.notna(row['epic']): return 'epic' return 'Na' # 逐行执行函数生成新列 df['promoted'] = df.apply(get_promoted_type, axis=1)
这种实现的优势是逻辑完全直白,没有额外理解成本,但本质是Python层的逐行循环,数据量越大性能损耗越明显。
np.select实现与效率对比
实现代码
np.select是基于NumPy的向量化批量判断逻辑,不需要逐行Python循环,只要按优先级顺序传入判断条件、对应返回值,指定所有条件不匹配的默认值即可:
# 按优先级顺序定义匹配条件 match_conditions = [ pd.notna(df['master_feature']), pd.notna(df['feature']), pd.notna(df['epic']) ] # 对应每个条件的返回结果 match_results = [ 'master feature', 'feature', 'epic' ] # 生成promoted列,无匹配时取默认值'Na' df['promoted'] = np.select(match_conditions, match_results, default='Na')
效率对比结论
- 性能上
np.select优势显著:在相同数据规模下,np.select的运行速度通常是df.apply逐行实现的10~100倍。核心原因是np.select的所有判断都在底层数组层面批量执行,没有Python层逐行循环的开销,数据量越大,两者的效率差距越明显。 - 输出结果完全一致:只要条件顺序严格匹配优先级要求,两种方法生成的
promoted列内容没有任何差异。
内容的提问来源于stack exchange,提问作者Devarshi Goswami
相关产品推荐
相关产品推荐

