如何提取DataFrame中非NA值的行名、列名及值并存入新DataFrame?
DataFrame非NA值宽转长实现方案
针对你需要提取所有非NA值、保留对应行名/列名/值的需求,不需要手写逐元素遍历逻辑,pandas内置的向量化方法可以高效完成处理,完全适配你20441行、158列的数据规模。
推荐实现:stack 方法
stack 会自动将DataFrame的列索引转换为二级行索引,且默认丢弃所有NA值,是当前场景下性能最优、代码最简洁的实现:
import pandas as pd import numpy as np # 以下为示例数据构造,实际使用时替换为你自己的DataFrame即可 df = pd.DataFrame( [[np.nan, np.nan, np.nan, 5, 6], [1, 3, np.nan, np.nan, np.nan]], index=['r1', 'r2'], columns=['c1', 'c2', 'c3', 'c4', 'c5'] ) # 核心转换逻辑,仅需2行 result = df.stack().reset_index() result.columns = ['行名', '所属列名', '值']
执行后得到的结果和你给出的期望输出完全匹配,针对你提到的数据规模,整体处理耗时通常在100毫秒以内。
备选实现:melt 方法
如果需要后续扩展更多转换规则,也可以使用melt先将宽表打平为长表,再过滤掉NA值:
result = df.melt(ignore_index=False, var_name='所属列名', value_name='值') .dropna(subset=['值']) .reset_index(names='行名')
该方法输出结果和stack完全一致,仅因为多一步NA过滤操作,性能略低于stack,但同样远高于手写循环逻辑。
注意:不要使用iterrows、itertuples或双层for循环逐单元格判断取值,这类循环写法在pandas中执行效率极低,处理当前规模的数据耗时会是内置方法的上百倍。
转换完成后你可以通过
result.reset_index(drop=True)重置新DataFrame的行索引,避免索引不连续的问题。
内容的提问来源于stack exchange,提问作者alireza
相关产品推荐
相关产品推荐

