如何在Pandas中为每行查找之前最接近close值的open值
问题描述
给定如下Pandas DataFrame:
timestamp open high low close delta atr last_index bearish bullish_turning_point 2 04-10-2024 01:54:44 18370.00 18377.75 18367.50 18376.00 32 0 1949 False True 5 04-10-2024 03:21:14 18376.50 18383.00 18375.25 18381.25 28 0 3899 False True 7 04-10-2024 04:38:54 18378.50 18386.25 18378.25 18385.50 133 0 5199 False True 9 04-10-2024 05:30:27 18384.00 18389.50 18378.75 18388.25 135 0 6499 False True 12 04-10-2024 06:06:12 18371.00 18378.00 18369.50 18378.00 130 0 8449 False True 14 04-10-2024 06:33:44 18372.25 18383.75 18372.00 18376.25 67 0 9749 False True 18 04-10-2024 07:21:14 18377.50 18387.75 18376.25 18380.00 8 0 12349 False True 22 04-10-2024 07:47:58 18388.00 18396.75 18385.25 18389.50 -30 0 14949 False True 25 04-10-2024 08:06:17 18390.75 18397.00 18387.50 18392.00 -25 0 16899 False True 28 04-10-2024 08:33:32 18384.75 18398.00 18383.25 18394.00 89 0 18849 False True 30 04-10-2024 08:54:35 18391.25 18403.00 18387.75 18399.25 84 0 20149 False True 34 04-10-2024 09:11:15 18388.75 18396.25 18385.75 18392.25 15 0 22749 False True 43 04-10-2024 10:02:22 18343.50 18350.50 18341.25 18350.50 113 0 28599 False True 46 04-10-2024 10:14:44 18352.00 18361.75 18352.00 18360.00 -42 0 30549 False True 49 04-10-2024 10:35:49 18354.00 18361.25 18347.75 18358.00 49 0 32499 False True 52 04-10-2024 10:54:18 18362.25 18372.00 18361.50 18372.00 180 0 34449 False True 56 04-10-2024 11:12:32 18369.25 18379.50 18367.00 18376.50 78 0 37049 False True 59 04-10-2024 11:27:27 18370.00 18376.50 18367.50 18373.25 54 0 38999 False True 65 04-10-2024 12:01:53 18377.75 18388.25 18377.50 18383.25 108 0 42899 False True 73 04-10-2024 12:25:04 18382.00 18386.25 18381.00 18384.75 65 0 48099 False True
需要为每一行查找该行之前所有行中,与当前行close值最接近的open值所在的行。比如:
- 原索引30的行,
close值为18399.25,对应原索引25的行的open值18390.75 - 原索引52的行,
close值为18372.00,对应原索引14的行的open值18372.25
解决方案
方法一:逐行遍历(直观易懂,适合小数据集)
这种方法用apply逐行处理,逻辑清晰,适合数据量不大的场景:
import pandas as pd # 保留原始索引方便后续匹配 df = df.reset_index(drop=False).rename(columns={'index': 'original_index'}) def get_closest_prev_row(row): # 筛选当前行之前的所有行 previous_rows = df.loc[:row.name - 1] if previous_rows.empty: return None # 第一行没有前置行,返回空值 # 计算每个前置行open与当前行close的绝对差值 diffs = abs(previous_rows['open'] - row['close']) # 找到差值最小的行的原始索引 closest_row_idx = diffs.idxmin() return previous_rows.loc[closest_row_idx, 'original_index'] # 为每行添加匹配到的前置行索引 df['closest_prev_open_row'] = df.apply(get_closest_prev_row, axis=1) # 验证示例结果 print(df[df['original_index'] == 30]['closest_prev_open_row']) # 输出25 print(df[df['original_index'] == 52]['closest_prev_open_row']) # 输出14
方法二:Numpy广播(高效处理大数据集)
如果数据集很大,逐行循环效率较低,可以用Numpy的矩阵运算提升速度:
import pandas as pd import numpy as np # 保留原始索引 df = df.reset_index(drop=False).rename(columns={'index': 'original_index'}) # 提取数值数组 close_array = df['close'].values open_array = df['open'].values # 创建差值矩阵:每行是当前close与所有open的绝对差 diff_matrix = np.abs(close_array[:, np.newaxis] - open_array[np.newaxis, :]) # 把当前行及之后的行的差值设为无穷大,只保留前置行的差值 np.fill_diagonal(diff_matrix, np.inf) for i in range(len(diff_matrix)): diff_matrix[i, i+1:] = np.inf # 找到每行差值最小的列索引(对应前置行的位置) closest_positions = np.argmin(diff_matrix, axis=1) # 第一行没有前置行,设为NaN closest_positions[0] = np.nan # 映射回原始索引 df['closest_prev_open_row'] = df.loc[closest_positions, 'original_index'].values
注意事项
- 如果存在多个
open值与当前close的差值相同,两种方法都会返回最早出现的那一行 - 若需要返回匹配行的其他信息(比如
timestamp、open值),只需修改函数中return的内容即可 - 大数据集优先选择Numpy方法,避免
apply的循环开销
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

