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

如何高效将股票Level2 Pandas DataFrame按价格递增转为单行多列?

高效转换股票Level2 Pandas DataFrame为单行多列格式(实时快照适配)

需求说明

将包含买卖盘(bid/ask)的股票Level2数据从多行格式,按价格递增规则转换为单行多列格式:

  • 以索引9(bid类型)和10(ask类型)为起始,生成price_bid_1、price_ask_1、volume_bid_1、volume_ask_1列
  • 依次遍历剩余行,生成price_bid_2、price_ask_2等对应列,直至所有行处理完成
  • 要求处理速度快,适配实时快照的低延迟场景

原始数据

import pandas as pd

df = pd.DataFrame({
    'price': {0: 1.0012, 1: 1.00115, 2: 1.0011, 3: 1.00105, 4: 1.001, 5: 1.00095, 6: 1.0009, 7: 1.00085, 8: 1.0008, 9: 1.00075, 10: 1.0007, 11: 1.00065, 12: 1.0006, 13: 1.00055, 14: 1.0005, 15: 1.00045, 16: 1.0004, 17: 1.00035, 18: 1.0003, 19: 1.00025},
    'volume': {0: 45.0, 1: 38.0, 2: 50.0, 3: 42.0, 4: 51.0, 5: 55.0, 6: 28.0, 7: 28.0, 8: 16.0, 9: 2.0, 10: 13.0, 11: 24.0, 12: 41.0, 13: 18.0, 14: 32.0, 15: 38.0, 16: 36.0, 17: 29.0, 18: 78.0, 19: 29.0},
    'type': {0: 'bid', 1: 'bid', 2: 'bid', 3: 'bid', 4: 'bid', 5: 'bid', 6: 'bid', 7: 'bid', 8: 'bid', 9: 'bid', 10: 'ask', 11: 'ask', 12: 'ask', 13: 'ask', 14: 'ask', 15: 'ask', 16: 'ask', 17: 'ask', 18: 'ask', 19: 'ask'}
})

解决方案

方法一:Numpy向量化实现(最优性能,适配实时场景)

完全基于Numpy的向量化操作,避免Python循环,处理速度比纯Pandas循环快数十倍,适合低延迟的实时快照场景。

import numpy as np

# 提取按价格递增排序的bid和ask数据
# bid从索引9到0(价格从低到高),ask从索引10到19
bid_data = df.loc[9::-1, ['price', 'volume']].values
ask_data = df.loc[10:, ['price', 'volume']].values

# 生成目标列名
n_levels = len(bid_data)
columns = []
for i in range(1, n_levels + 1):
    columns.extend([
        f'price_bid_{i}',
        f'price_ask_{i}',
        f'volume_bid_{i}',
        f'volume_ask_{i}'
    ])

# 拼接并展平数据,生成单行结果
flattened_data = np.column_stack([bid_data, ask_data]).flatten()
result = pd.DataFrame([flattened_data], columns=columns)

# 查看结果
print(result)

方法二:Pandas pivot拼接实现(代码简洁)

用Pandas的pivot功能转换宽表,代码可读性强,性能虽略逊于Numpy,但仍能满足大部分场景需求。

# 给bid/ask添加层级编号,bid按价格递增排序(反转原顺序)
bid_df = df[df['type'] == 'bid'].iloc[::-1].reset_index(drop=True)
bid_df['level'] = bid_df.index + 1

ask_df = df[df['type'] == 'ask'].reset_index(drop=True)
ask_df['level'] = ask_df.index + 1

# 转换为宽表并调整列结构
bid_wide = bid_df.pivot(columns='level', values=['price', 'volume']).swaplevel(0, 1, axis=1).sort_index(axis=1)
ask_wide = ask_df.pivot(columns='level', values=['price', 'volume']).swaplevel(0, 1, axis=1).sort_index(axis=1)

# 重命名列
bid_wide.columns = [f'{col[1]}_{col[0]}_bid' for col in bid_wide.columns]
ask_wide.columns = [f'{col[1]}_{col[0]}_ask' for col in ask_wide.columns]

# 按目标列顺序合并结果
result = pd.concat([bid_wide, ask_wide], axis=1).reindex(columns=columns)

# 查看结果
print(result)

性能说明

  • Numpy向量化方法:所有操作在C语言层面执行,无Python循环,延迟极低,是实时场景的首选方案
  • Pandas pivot方法:代码更易维护,但涉及Pandas内部的对象操作,性能略低于Numpy方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:01:04