使用Pandas实现:columnA非空时提取首项非负数至新列
基于DataFrame生成新列valueD的实现方案
需求说明
需要基于DataFrame的valueA、valueB、valueC三列生成新列valueD,规则如下:
- 当
columnA不等于None时,取valueA、valueB、valueC中的第一个非负数填入valueD - 当
columnA为None时,valueD直接设为None
示例数据
原始DataFrame:
columnA valueA valueB valueC None -40 -41 -42 A -5 10 20 B -10 -5 10 C 1 2 3
处理后的结果:
columnA valueA valueB valueC valueD None -40 -41 -42 None A -5 10 20 10 B -10 -5 10 10 C 1 2 3 1
实现方法
方法1:自定义函数+apply(直观易懂,适合小数据集)
先构造示例DataFrame,再通过apply遍历每行执行逻辑:
import pandas as pd # 构造示例数据 data = { 'columnA': [None, 'A', 'B', 'C'], 'valueA': [-40, -5, -10, 1], 'valueB': [-41, 10, -5, 2], 'valueC': [-42, 20, 10, 3] } df = pd.DataFrame(data) # 定义处理每行的函数 def get_first_non_negative(row): # columnA为None时直接返回None if pd.isna(row['columnA']): return None # 按顺序检查valueA、valueB、valueC,返回第一个非负数 for col in ['valueA', 'valueB', 'valueC']: if row[col] >= 0: return row[col] # 若三列全为负数,返回None(可根据需求调整) return None # 生成valueD列 df['valueD'] = df.apply(get_first_non_negative, axis=1)
方法2:矢量化操作(效率更高,适合大数据集)
避免逐行循环,用Pandas的矢量化方法提升性能:
import pandas as pd # 构造示例数据 data = { 'columnA': [None, 'A', 'B', 'C'], 'valueA': [-40, -5, -10, 1], 'valueB': [-41, 10, -5, 2], 'valueC': [-42, 20, 10, 3] } df = pd.DataFrame(data) # 标记需要处理的行(columnA不为None) mask = df['columnA'].notna() # 找出每行第一个非负数所在的列名 value_cols = ['valueA', 'valueB', 'valueC'] first_non_neg_cols = df.loc[mask, value_cols] >= 0 first_non_neg_cols = first_non_neg_cols.idxmax(axis=1) # 根据列名提取对应的值,赋值给valueD df.loc[mask, 'valueD'] = df.loc[mask].apply(lambda x: x[first_non_neg_cols.loc[x.name]], axis=1) # 不需要处理的行设为None df.loc[~mask, 'valueD'] = None
两种方法运行后都能得到示例中的结果,可根据数据集大小选择合适的方案。
内容的提问来源于stack exchange,提问作者PV8
相关产品推荐
相关产品推荐

