问题描述
解决方案
在 JoinQuant(聚宽)的 get_price 函数中,panel 和 dataframe 是两种不同的数据返回格式,它们的区别主要取决于查询标的数量以及 panel 参数的设置。
以下是详细的区别说明:
1. 数据结构维度的区别
-
DataFrame (二维数据)
- 场景:
- 查询单只股票时(默认返回)。
- 查询多只股票且设置参数
panel=False时。
- 结构:这是一个二维的表格结构(行 x 列)。
- 单只股票时:行索引(Index)是时间(datetime),列索引(Columns)是行情字段(如 open, close, high 等)。
- 多只股票时 (panel=False):通常返回一个多级索引(MultiIndex)的 DataFrame,或者结构等效的二维表,方便在较新版本的 Pandas 中处理。
- 场景:
-
Panel (三维数据)
- 场景:查询多只股票且参数
panel=True(默认值通常为 True,但在新版 Pandas 中已废弃)时。 - 结构:这是一个三维的数据容器,可以看作是多个 DataFrame 的集合。
- 三个维度:
- Items (项目):行情字段(如 open, close, volume)。
- Major_axis (主轴):时间(datetime)。
- Minor_axis (副轴):股票代码(security)。
- 场景:查询多只股票且参数
2. 数据获取方式的区别
假设我们获取了多只股票的数据:data = get_price(['000001.XSHE', '000002.XSHE'], ...)
-
如果是 Panel 格式 (
panel=True):
你需要先选“字段”,再选“股票”或“时间”。# 获取所有股票的开盘价(返回一个 DataFrame,行是时间,列是股票代码) df_open = data['open'] # 获取平安银行在特定时间的开盘价 price = data['open']['2023-01-01']['000001.XSHE'] -
如果是 DataFrame 格式 (单只股票):
直接通过字段名获取 Series。# data 是一个 DataFrame # 获取开盘价序列 series_open = data['open']
3. 兼容性与建议 (重要)
- Panel 已被废弃:Python 的数据分析库 Pandas 从 0.25 版本开始已经彻底移除了 Panel 数据结构。
- 推荐做法:在调用
get_price获取多只股票数据时,强烈建议设置panel=False。这样返回的数据是 DataFrame 格式,兼容性更好,且支持 Pandas 的所有最新功能。
总结对比
| 特性 | DataFrame | Panel |
|---|---|---|
| 维度 | 2维 (行, 列) | 3维 (Items, Major, Minor) |
| 适用场景 | 单只股票,或多只股票(panel=False) |
多只股票(panel=True) |
| Pandas支持 | 完全支持 (主流格式) | 已移除 (Pandas >= 0.25 不支持) |
| 建议 | 推荐使用 | 不推荐使用 |
代码示例
1. 获取单只股票 (返回 DataFrame)
# 返回 DataFrame,Index是时间,Columns是 open, close 等
df = get_price('000001.XSHE', count=5)
print(type(df)) # <class 'pandas.core.frame.DataFrame'>
print(df['close']) # 获取收盘价 Series
2. 获取多只股票 (推荐设置 panel=False)
# 建议显式设置 panel=False,返回兼容性更好的 DataFrame
df_multi = get_price(['000001.XSHE', '000002.XSHE'], count=5, panel=False)
print(type(df_multi)) # <class 'pandas.core.frame.DataFrame'>
Q&A
Q: 为什么我的策略报错 ImportError: cannot import name 'Panel' from 'pandas'?
A: 这是因为您的回测环境使用了较新版本的 Pandas (0.25+),其中 Panel 已被移除。解决方法是在调用 get_price 时添加参数 panel=False,或者修改代码逻辑以适应 DataFrame 结构。
Q: 如果我必须使用 Panel 的操作逻辑怎么办?
A: 如果您习惯了 Panel 的切片方式(例如 data['open'] 获取所有股票的开盘价矩阵),在设置 panel=False 后,您可以使用 Pandas 的 .to_xarray() 转为 xarray 对象,或者利用 MultiIndex 的切片方法,但最简单的方法是适应 DataFrame 的操作习惯。
Q: get_price 获取多只股票时,如果不写 panel 参数,默认是什么?
A: 根据文档,默认通常是为了兼容旧代码的 Panel 结构(如果 Pandas 版本允许)。但在新环境中,为了避免错误,请务必显式指定 panel=False。