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

如何在Pandas DataFrame行中查找最后一个索引并按列反向计算差值

Pandas实现:按行计算连续有效块的反向列差值

先把你的需求用代码还原出来,方便大家理解:

原始DataFrame

import pandas as pd
import numpy as np

df = pd.DataFrame(
    [
        [1, 1, 1, 1, np.nan, np.nan, np.nan],
        [1, 1, 1, 1, 1, 1, np.nan],
        [1, 1, 1, 1, np.nan, np.nan, np.nan],
        [1, 1, np.nan, np.nan, 1, 1, 1]
    ],
    index=[1,2,3,4],
    columns=[20,40,60,80,100,120,140]
)

目标输出

20   40   60   80   100  120  140
1   40   20    0  NaN   NaN  NaN  NaN
2   80   60   40   20    0  NaN  NaN
3   60   40   20    0   NaN  NaN  NaN
4   20    0  NaN  NaN   40   20    0

核心需求其实是:对每行的每个连续非NaN区域,找到该区域的最后一列的列名,然后区域内每个位置的值 = 最后列名 - 当前列名,非区域位置保持NaN。接下来一步步实现:


步骤1:标记每行的连续有效块

首先得把每行里的连续非NaN区域区分开,给每个块分配唯一ID:

# 先得到非NaN的布尔矩阵
not_nan = df.notna()
# 按行计算连续块的ID:遇到NaN或者和前一列状态不同时,ID递增
group_ids = not_nan.cumsum(axis=1) * not_nan

group_ids里,同一个连续有效块的位置会有相同的数字ID,NaN位置则是0,这样我们就能精准定位每个独立的块。

步骤2:获取每个块的最后列名

接下来要针对每个块,找到它的最后一列的列名。这里用transform方法按行处理:

# 把列名转换成和DataFrame同形状的矩阵,方便按位置取值
col_names = np.tile(df.columns, (len(df), 1))
# 对每行的每个分组,取该块最后一列的列名
last_col = group_ids.transform(lambda x: col_names[x.index, x.idxmax()], axis=1)

x.idxmax()会返回当前分组在该行的最后一个非0位置(也就是块的最后一列索引),然后我们从col_names里取出对应的列名,这样每个块内的所有位置都会拿到该块的最后列名。

步骤3:计算差值并保留原始NaN

最后一步很简单,用每个块的最后列名减去当前列名,再用where把原始NaN的位置还原回去:

result = (last_col - df.columns).where(not_nan)

where(not_nan)会只保留原始非NaN位置的计算结果,NaN位置依然是NaN,完美匹配你的目标输出。


完整运行代码

把上面的步骤整合起来,直接运行就能得到结果:

import pandas as pd
import numpy as np

# 构建原始DataFrame
df = pd.DataFrame(
    [
        [1, 1, 1, 1, np.nan, np.nan, np.nan],
        [1, 1, 1, 1, 1, 1, np.nan],
        [1, 1, 1, 1, np.nan, np.nan, np.nan],
        [1, 1, np.nan, np.nan, 1, 1, 1]
    ],
    index=[1,2,3,4],
    columns=[20,40,60,80,100,120,140]
)

# 1. 标记连续有效块
not_nan = df.notna()
group_ids = not_nan.cumsum(axis=1) * not_nan

# 2. 获取每个块的最后列名
col_names = np.tile(df.columns, (len(df), 1))
last_col = group_ids.transform(lambda x: col_names[x.index, x.idxmax()], axis=1)

# 3. 计算差值并保留NaN
result = (last_col - df.columns).where(not_nan)

print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:10:53