如何用Python/Pandas将行中实体右移至末尾(适配可变Date列)
问题:DataFrame行内有效数据右移至末尾(针对最后一列含NaN的行)
现有如下DataFrame(Date列数量可变):
Customer Date1 Date2 Date3 Date4
0 A 10 40.0 NaN 60.0
1 B 20 50.0 NaN NaN
2 C 30 NaN NaN NaN
要求:若最后一列存在NaN,将该行的所有有效数据右移至DataFrame末尾,处理后结果如下:
Customer Date1 Date2 Date3 Date4
0 A 10 40.0 NaN 60.0
1 B NaN NaN 20 50.0
2 C NaN NaN NaN 30
空缺值设为NaN。尝试了以下代码但未成功:
import numpy as np import pandas as pd data = { 'Customer': ['A', 'B', 'C'], 'Date1': [10, 20, 30], 'Date2': [40, 50, np.nan], 'Date3': [np.nan, np.nan, np.nan], 'Date4': [60, np.nan, np.nan] } df = pd.DataFrame(data) for i in range(1, len(df.columns)): df.iloc[:, i] = df.iloc[:, i-1].shift(fill_value=np.nan) print(df)
解决方案
核心思路是针对每行日期数据,提取有效数值后左补NaN,让有效数据对齐到列末尾,具体实现如下:
import numpy as np import pandas as pd data = { 'Customer': ['A', 'B', 'C'], 'Date1': [10, 20, 30], 'Date2': [40, 50, np.nan], 'Date3': [np.nan, np.nan, np.nan], 'Date4': [60, np.nan, np.nan] } df = pd.DataFrame(data) # 分离客户列与日期列 customer_col = df['Customer'] date_cols = df.drop('Customer', axis=1) # 处理每行日期数据:提取有效数值,左补NaN对齐到末尾 processed_dates = date_cols.apply( lambda row: np.concatenate( [[np.nan]*(len(date_cols.columns)-len(row.dropna())), row.dropna().values] ), axis=1 ).apply(pd.Series) # 合并列并恢复原列名 result_df = pd.concat([customer_col, processed_dates], axis=1) result_df.columns = df.columns print(result_df)
代码说明
- 列分离:将
Customer列单独保留,剩余日期列单独处理,避免干扰客户标识 - 行处理逻辑:
- 对每行日期数据,用
dropna()提取所有非NaN的有效数值 - 计算需要左补的NaN数量:总日期列数减去有效数值的个数
- 拼接NaN数组与有效数值数组,实现有效数据右移至列末尾
- 对每行日期数据,用
- 合并恢复:将处理后的日期列与客户列合并,恢复原DataFrame的列名结构
此方法不受Date列数量限制,任意数量的日期列都能适配处理。
内容的提问来源于stack exchange,提问作者dark water
相关产品推荐
相关产品推荐

