如何实现Pandas数据框每行非空值左移,从左到右填充列?
解决Pandas每行非缺失值左移填充的问题
嘿,这个需求我之前碰到过,给你分享两个简便的解决方案,完美实现你要的“每行非NaN值向左对齐,优先填满左侧列,右侧补NaN”的效果!
先明确需求对比
原始数据:
import pandas as pd import numpy as np df = pd.DataFrame({ 'A':[1,2,np.nan,np.nan,3], 'B':[2,3,np.nan,5,2], 'C':[2,3,7,5,9], 'D':[1,2,3,np.nan,np.nan] })
目标效果:每行的非缺失值依次左移,填充左侧列,原列顺序保留,右侧空缺补NaN。
方法1:简洁的apply逐行处理(适合小数据集)
利用apply逐行操作,先移除每行的NaN值,再重新对齐到原列索引上:
df_shifted = df.apply( lambda row: pd.Series(row.dropna().values, index=row.index[:len(row.dropna())]), axis=1 )
原理说明:
- 对每行执行
row.dropna(),得到该行所有非NaN值的序列; - 用原行的前N个索引(N是该行非NaN值的数量)来构建新的Series,这样非NaN值会自动填充到左侧列,剩下的列因为没有对应值,会被自动填充为NaN。
方法2:高效的numpy实现(适合大数据集)
如果你的数据集很大,apply逐行处理可能较慢,用numpy操作会更高效:
# 获取每行非NaN值的数量 non_nan_counts = df.notna().sum(axis=1) # 创建和原DataFrame形状一致的空数组,初始填充NaN result_array = np.full(df.shape, np.nan) # 遍历每行,将非NaN值填充到数组左侧 for idx in range(df.shape[0]): # 提取当前行的非NaN值,填充到数组的对应行左侧 result_array[idx, :non_nan_counts[idx]] = df.iloc[idx].dropna().values # 转换回DataFrame,保留原列名和索引 df_shifted = pd.DataFrame(result_array, columns=df.columns, index=df.index)
原理说明:
- 先统计每行有多少个非NaN值;
- 创建一个和原数据形状相同的NaN数组;
- 把每行的非NaN值依次放到数组的左侧位置,剩下的位置保持NaN;
- 最后转换回Pandas DataFrame即可。
验证结果
运行任意一种方法后,打印df_shifted就能得到你想要的结果:
A B C D 0 1.0 2.0 2.0 1.0 1 2.0 3.0 3.0 2.0 2 7.0 3.0 NaN NaN 3 5.0 5.0 NaN NaN 4 3.0 2.0 9.0 NaN
完全匹配你给出的目标格式!
内容的提问来源于stack exchange,提问作者Beertje
相关产品推荐
相关产品推荐

