You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

快速获取Pandas DataFrame行/列中非空值索引的高效方法

高效提取每行非NaN值的列名(大数据集优化方案)

给定如下Pandas DataFrame:

import pandas as pd

df = pd.DataFrame({
    'a': {0: 3.0, 1: 2.0, 2: None}, 
    'b': {0: 10.0, 1: None, 2: 8.0}, 
    'c': {0: 4.0, 1: 2.0, 2: 6.0}
})

输出为:

a     b    c
0  3.0  10.0  4.0
1  2.0   NaN  2.0
2  NaN   8.0  6.0

原需求是生成新DataFrame,每行对应原DataFrame该行所有非NaN值的列名。原方法使用apply逐行处理:

df2 = df.apply(lambda x: pd.Series(x.dropna().index), axis=1)

输出符合预期,但apply本质是逐行执行Python循环,在大数据集下性能较差。以下是两种更高效的实现方式:

方法1:利用stack()结合分组(推荐)

stack()是Pandas的向量化操作,性能远优于逐行apply:

# 堆叠非空值,保留原始行索引和列名
stacked = df.stack().reset_index(level=1)
# 按行索引分组,收集列名并展开为DataFrame
df2 = stacked.groupby(level=0)['level_1'].apply(list).apply(pd.Series)

执行后得到的结果和原方法一致:

0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

方法2:基于NumPy布尔矩阵的列表推导

通过NumPy直接操作布尔矩阵,避免Pandas的逐行循环开销:

# 获取非空值的布尔矩阵
mask = df.notna().to_numpy()
# 逐行提取对应列名,生成列表
col_lists = [df.columns[row_mask].tolist() for row_mask in mask]
# 转换为DataFrame,自动补全NaN到最长行的长度
df2 = pd.DataFrame(col_lists)

关于获取每列非空值的行索引

如果需要获取每列的非空值行索引,只需转置原DataFrame后使用上述任意一种方法即可,例如:

# 转置后用stack方法处理
df_T = df.T.stack().reset_index(level=1)
col_non_null_rows = df_T.groupby(level=0)['level_1'].apply(list).apply(pd.Series)

内容的提问来源于stack exchange,提问作者younggotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:52