基于多列值创建新列:DataFrame按条件生成列d的需求
根据多列非空条件生成新列d的解决方案
问题需求
需要为DataFrame生成列d,规则如下:
- 若列
a含数值且b、c列为空,d填'a' - 若列
b含数值且a、c列为空,d填'b' - 若列
c含数值且a、b列为空,d填'c' - 若
a、b列均含数值且c列为空,d填'ab' - 若
a、c列均含数值且b列为空,d填'ac' - 若
b、c列均含数值且a列为空,d填'bc' - 若
a、b、c列均含数值,d填'abc'
现有代码的问题
当前代码存在两个核心问题:
- 逻辑覆盖不全:用
elif只会匹配第一个满足的条件,无法处理多列同时有值的场景(比如a和b都有值时,代码只会返回'a',不符合规则4)。 - 未判断其他列的空值状态:代码仅判断当前列是否>=1,但没验证其他列是否为空,完全不符合需求里的“仅某列/某几列有值,其余为空”的前提。
正确解法
方法1:自定义逐行处理函数(直观易读)
这种方法逻辑清晰,适合小规模数据集:
import pandas as pd # 模拟你的DataFrame(可替换为实际数据) df = pd.DataFrame({ 'a': [1, None, 2, 3, None, None, 4], 'b': [None, 5, 6, None, 7, 8, 9], 'c': [None, None, None, 10, 11, 12, 13] }) def get_col_d(row): # 标记各列是否有有效数值 a_valid = not pd.isna(row['a']) b_valid = not pd.isna(row['b']) c_valid = not pd.isna(row['c']) # 按规则匹配返回值 if a_valid and not b_valid and not c_valid: return 'a' elif b_valid and not a_valid and not c_valid: return 'b' elif c_valid and not a_valid and not b_valid: return 'c' elif a_valid and b_valid and not c_valid: return 'ab' elif a_valid and c_valid and not b_valid: return 'ac' elif b_valid and c_valid and not a_valid: return 'bc' elif a_valid and b_valid and c_valid: return 'abc' return '' # 全为空时的默认值,可按需修改 df['d'] = df.apply(get_col_d, axis=1) print(df)
方法2:向量化操作(高效适合大数据集)
用numpy.select实现向量化判断,避免逐行循环,效率更高:
import pandas as pd import numpy as np # 模拟你的DataFrame(可替换为实际数据) df = pd.DataFrame({ 'a': [1, None, 2, 3, None, None, 4], 'b': [None, 5, 6, None, 7, 8, 9], 'c': [None, None, None, 10, 11, 12, 13] }) # 生成各列的非空掩码 mask_a = df['a'].notna() mask_b = df['b'].notna() mask_c = df['c'].notna() # 定义条件列表和对应结果 conditions = [ mask_a & ~mask_b & ~mask_c, mask_b & ~mask_a & ~mask_c, mask_c & ~mask_a & ~mask_b, mask_a & mask_b & ~mask_c, mask_a & mask_c & ~mask_b, mask_b & mask_c & ~mask_a, mask_a & mask_b & mask_c ] results = ['a', 'b', 'c', 'ab', 'ac', 'bc', 'abc'] # 生成列d df['d'] = np.select(conditions, results, default='') print(df)
内容的提问来源于stack exchange,提问作者hxgx_0990
相关产品推荐
相关产品推荐

