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

如何用Pythonic/Pandas-onic方式计算DataFrame行与后续行的最大差值?

Pandas高效实现指定行间最大差值计算

先明确需求和示例数据:
我们有如下结构的DataFrame:

import pandas as pd

df = pd.DataFrame({
    'High': [100, 110, 105],
    'Low': [90, 95, 80]
})

需要计算每一行的High值,减去自身及后续所有行的Low值,找出所有差值中的最大值,并返回对应的(High值, Low值)或它们的索引对(High行索引, Low行索引)。比如示例中最大差值为30,对应(110, 80)或(1, 2)。

方案一:向量化矩阵运算(直观高效)

利用Numpy的广播机制生成所有符合条件的差值,直接定位最大值位置,彻底避免循环:

import numpy as np

# 生成High列的列向量和Low列的行向量,广播计算所有High-Low的差值
diff_matrix = df['High'].values[:, None] - df['Low'].values[None, :]
# 创建掩码,只保留j >= i的位置(j是Low的行索引,i是High的行索引)
mask = np.triu(np.ones(diff_matrix.shape, dtype=bool), k=0)
# 过滤掉不符合条件的差值(设为NaN,不参与最大值计算)
diff_matrix[~mask] = np.nan

# 找出最大值的位置(行索引=High所在行,列索引=Low所在行)
high_idx, low_idx = np.unravel_index(np.nanargmax(diff_matrix), diff_matrix.shape)

# 获取结果
result_values = (df.loc[high_idx, 'High'], df.loc[low_idx, 'Low'])
result_indices = (high_idx, low_idx)

print(f"数值对:{result_values}")
print(f"索引对:{result_indices}")

方案二:Pandas窗口函数(内存友好)

针对大行数场景,用expanding窗口计算后续行的最小Low值,避免构造全量差值矩阵,降低内存占用:

# 计算从当前行到末尾的Low最小值(从后往前用expanding窗口,再反转回来)
rev_low = df['Low'][::-1]
min_low_from_current = rev_low.expanding().min()[::-1]

# 找出每个行对应的后续最小Low值的索引
def get_min_low_idx(row):
    start_idx = df.index.get_loc(row.name)
    return df['Low'].iloc[start_idx:].idxmin()

min_low_indices = df.apply(get_min_low_idx, axis=1)

# 计算每个行的最大可能差值
df['max_diff'] = df['High'] - min_low_from_current

# 定位最大差值的位置
max_high_idx = df['max_diff'].idxmax()
max_low_idx = min_low_indices[max_high_idx]

# 获取结果
result_values = (df.loc[max_high_idx, 'High'], df.loc[max_low_idx, 'Low'])
result_indices = (max_high_idx, max_low_idx)

print(f"数值对:{result_values}")
print(f"索引对:{result_indices}")

方案优势

两种方法均比双重循环高效得多:

  • 方案一逻辑直观,适合小到中等规模的DataFrame,运算速度快
  • 方案二无需构造全量差值矩阵,内存占用更低,适合行数较多的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:04:59