如何合并求和时间戳未对齐的两类资产订单簿时间序列?
合并不同时间戳的订单簿数据并求和
双指针法的可行性
双指针法本身是完全可行的,你之前没生效大概率是边界条件处理不到位(比如其中一个数组遍历完后,另一个数组剩余元素的收尾逻辑),或是最新值更新的逻辑有误。只要把这两点修正,这个方法就能正常工作。
双指针法的具体实现
假设你有两个DataFrame:df_a(资产A)和df_b(资产B),都包含timestamp(Unix时间戳)和需要求和的字段(比如order_size)。实现步骤如下:
- 先对两个DataFrame按时间戳升序排序:双指针法依赖有序的时间序列,这一步是前提。
- 初始化变量:两个遍历指针
i=0(对应df_a)、j=0(对应df_b);记录当前资产的最新值current_a=0、current_b=0;存储结果的列表result = []。 - 循环处理直到所有数据遍历完成:
- 分别获取当前指针指向的时间戳,若指针越界则设为无穷大(方便判断优先级)。
- 分三种情况处理:
- 当资产A的时间戳更早(或资产B已遍历完):更新资产A的最新值,计算总和,将时间戳与总和存入结果,移动资产A的指针。
- 当资产B的时间戳更早(或资产A已遍历完):更新资产B的最新值,计算总和,将时间戳与总和存入结果,移动资产B的指针。
- 当两个时间戳相同时:同时更新两类资产的最新值,计算总和,存入结果后同时移动两个指针。
代码示例
import pandas as pd # 示例数据 df_a = pd.DataFrame({'timestamp': [100, 300, 500], 'order_size': [10, 20, 30]}) df_b = pd.DataFrame({'timestamp': [200, 300, 600], 'order_size': [5, 15, 25]}) # 关键步骤:按时间戳排序 df_a = df_a.sort_values('timestamp').reset_index(drop=True) df_b = df_b.sort_values('timestamp').reset_index(drop=True) i = j = 0 len_a, len_b = len(df_a), len(df_b) current_a = current_b = 0 result = [] while i < len_a or j < len_b: # 获取当前时间戳,越界则设为无穷大 ts_a = df_a.iloc[i]['timestamp'] if i < len_a else float('inf') ts_b = df_b.iloc[j]['timestamp'] if j < len_b else float('inf') if ts_a < ts_b: current_a = df_a.iloc[i]['order_size'] result.append({'timestamp': ts_a, 'total_size': current_a + current_b}) i += 1 elif ts_b < ts_a: current_b = df_b.iloc[j]['order_size'] result.append({'timestamp': ts_b, 'total_size': current_a + current_b}) j += 1 else: current_a = df_a.iloc[i]['order_size'] current_b = df_b.iloc[j]['order_size'] result.append({'timestamp': ts_a, 'total_size': current_a + current_b}) i += 1 j += 1 # 转为最终DataFrame final_df = pd.DataFrame(result) print(final_df)
更简便的Pandas内置方法
如果不想手动写双指针逻辑,也可以用Pandas的merge_asof快速实现:
- 生成包含所有唯一时间戳的序列。
- 用
merge_asof为每个时间戳匹配两类资产的最新值(direction='backward'表示取小于等于当前时间戳的最新数据)。 - 对匹配后的数值求和即可。
代码示例
# 承接上面的示例数据 # 生成所有唯一时间戳的有序序列 all_timestamps = pd.Series( sorted(set(df_a['timestamp'].tolist() + df_b['timestamp'].tolist())), name='timestamp' ) # 匹配每个时间戳对应的最新资产数据 merged_a = pd.merge_asof(all_timestamps, df_a, on='timestamp', direction='backward').fillna(0) merged_b = pd.merge_asof(all_timestamps, df_b, on='timestamp', direction='backward').fillna(0) # 计算总和 final_df = pd.DataFrame({ 'timestamp': all_timestamps, 'total_size': merged_a['order_size'] + merged_b['order_size'] }) print(final_df)
这个方法无需手动处理边界逻辑,代码更简洁,适合大多数场景。
内容的提问来源于stack exchange,提问作者Toilet Paper
相关产品推荐
相关产品推荐

