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

如何对多列DataFrame按分组行方向移位非NaN值(保留NaN)

问题:DataFrame按列跳过NaN向下移位n行(保留原NaN位置)

我有如下DataFrame:

A1A2A3A4A5A6
1nan37nan8
nan5nan119nan
54684123nan
10nannan16nan45
12931331591
73nan45nannan9

希望将整个DataFrame向下移位n行(示例n=2),移位时跳过NaN值但保留原有NaN的位置,期望输出如下:

A1A2A3A4A5A6
nannannannannannan
nannannannannannan
nannannan7nannan
1nannan11nannan
54531298
10nan84nannan45

我尝试过以下代码,但仅适用于少量列:

df['dummy'] = df.apply(lambda x: 1 if pd.notnull(x[column]) else 0, axis=1)
df['dummy2'] = df.groupby(['dummy'])[column].shift(n)
df[column] = df.apply(lambda x: x['dummy2'] if x['dummy']==1 else x[column], axis=1)

还生成了dummy DataFrame:

dummy_df = df.applymap(lambda x: 1 if pd.notnull(x) else 0)

但不清楚后续操作。现在需要处理数千列的移位需求,希望用最少循环实现,能否借助dummy_df结合groupby完成?


解决方案

针对数千列的场景,最高效的方式是按列独立处理,利用apply对每列执行跳过NaN的移位逻辑,无需显式循环,也不需要dummy_df或groupby。核心思路是:对每一列,先提取非NaN值进行移位,再将移位后的值放回原列的非NaN位置,保留原始NaN的位置。

实现代码如下:

import pandas as pd
import numpy as np

# 定义处理单列的函数
def shift_non_nan(column, shift_n):
    # 提取列中的非NaN值并移位,前面补shift_n个NaN
    non_nan_vals = column.dropna()
    shifted_vals = non_nan_vals.shift(shift_n)
    # 将移位后的值映射回原列,原NaN位置保持NaN
    return column.where(column.isna(), shifted_vals)

# 示例DataFrame
data = {
    'A1': [1, np.nan, 54, 10, 12, 73],
    'A2': [np.nan, 5, 6, np.nan, 93, np.nan],
    'A3': [3, np.nan, 84, np.nan, 13, 45],
    'A4': [7, 11, 12, 16, 31, np.nan],
    'A5': [np.nan, 9, 3, np.nan, 5, np.nan],
    'A6': [8, np.nan, np.nan, 45, 91, 9]
}
df = pd.DataFrame(data)

# 执行移位(n=2)
n = 2
df_shifted = df.apply(lambda col: shift_non_nan(col, n), axis=0)

print(df_shifted)

输出结果与预期一致:

A1   A2    A3    A4   A5    A6
0  NaN  NaN   NaN   NaN  NaN   NaN
1  NaN  NaN   NaN   NaN  NaN   NaN
2  NaN  NaN   NaN   7.0  NaN   NaN
3  1.0  NaN   NaN  11.0  NaN   NaN
4 54.0  5.0   3.0  12.0  9.0   8.0
5 10.0  NaN  84.0   NaN  NaN  45.0

为什么这个方法适合数千列?

  • apply(axis=0)会自动遍历每一列,无需手动写循环,代码简洁。
  • 每列的处理都是矢量化操作(dropna、shift、where都是Pandas的高效内置方法),性能远高于逐元素循环。
  • 逻辑清晰,直接针对“跳过NaN移位+保留原NaN位置”的需求,避免了dummy_df和groupby的复杂操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:01:21