如何在Pandas中提取每行多列非空值并生成Intersection列
解决方案
你可以通过两种方式实现需求:一种是逐行处理的简洁写法,另一种是适合大数据集的矢量化操作。
方法一:逐行处理(简洁直观)
通过apply逐行筛选非空值,再根据非空值数量决定返回单个元素还是列表:
import pandas as pd import numpy as np data = {'Col1': ['A', np.nan, np.nan, np.nan, np.nan], 'Col2': [np.nan, 'B', np.nan, 'E', np.nan], 'Col3': [np.nan, 'C', np.nan, np.nan, np.nan], 'Col4': [np.nan, np.nan, 'D', np.nan, np.nan], 'Col5': [np.nan, np.nan, np.nan, np.nan, 'F'] } df = pd.DataFrame(data) # 定义每行的处理逻辑 def extract_non_null(row): non_null_vals = row.dropna().tolist() return non_null_vals[0] if len(non_null_vals) == 1 else non_null_vals # 添加目标列 df['Intersection'] = df.apply(extract_non_null, axis=1) print(df)
输出结果
Col1 Col2 Col3 Col4 Col5 Intersection 0 A NaN NaN NaN NaN A 1 NaN B C NaN NaN [B, C] 2 NaN NaN NaN D NaN D 3 NaN E NaN NaN NaN E 4 NaN NaN NaN NaN F F
方法二:矢量化操作(高性能)
如果处理的数据集较大,推荐用stack()结合分组操作替代逐行apply,性能更优:
import pandas as pd import numpy as np data = {'Col1': ['A', np.nan, np.nan, np.nan, np.nan], 'Col2': [np.nan, 'B', np.nan, 'E', np.nan], 'Col3': [np.nan, 'C', np.nan, np.nan, np.nan], 'Col4': [np.nan, np.nan, 'D', np.nan, np.nan], 'Col5': [np.nan, np.nan, np.nan, np.nan, 'F'] } df = pd.DataFrame(data) # 按行分组提取非空值列表 non_null_groups = df.stack().groupby(level=0).apply(list) # 处理单个元素的情况 df['Intersection'] = non_null_groups.apply(lambda x: x[0] if len(x) == 1 else x) print(df)
逻辑说明
df.stack():将DataFrame的非空值按行堆叠,自动过滤NaNgroupby(level=0):按原行索引分组,聚合每行的非空值为列表- 最后通过lambda函数判断列表长度,转换单个元素的格式
内容的提问来源于stack exchange,提问作者user19956605
相关产品推荐
相关产品推荐

