如何用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
相关产品推荐
相关产品推荐

