3、数据格式与存储:CSV、Parquet、HDF5格式对比,Pandas DataFrame基础操作
做量化研究,第一步就是跟数据打交道。我见过太多人一上来就写策略,结果数据读进来全是错的,白忙活半天。今天咱们就把数据格式和存储这件事彻底聊透。
3.1 三种主流格式:CSV、Parquet、HDF5
先说结论:没有完美的格式,只有适合的场景。我个人的习惯是——小数据用CSV,大数据用Parquet,需要频繁读写结构化数据用HDF5。
CSV:最通用的格式,但效率最低
CSV的好处是任何工具都能打开。Excel、Notepad、甚至记事本都能看。但它的缺点也很明显:
- 没有数据类型:你存个日期进去,读出来是字符串,还得自己转
- 占用空间大:同样的数据,CSV比Parquet大3-5倍
- 读取慢:尤其是几千万行的大文件,读一次能急死人
Parquet:列式存储,量化研究的首选
Parquet是列式存储格式。什么意思呢?就是它把每一列的数据单独存。你想想看,做因子测试时,我们经常只取某几列数据,比如只取'close'和'volume'。列式存储就能只读这两列,速度飞快。
我曾在项目中处理过5年A股的全量分钟数据,大概有2亿行。用CSV读一次要15分钟,换成Parquet后,同样的数据只要40秒。这差距,你品品。
- 压缩率高:同样的数据,体积只有CSV的20%-30%
- 读取速度快:尤其是只读部分列时
- 自带schema:数据类型、列名都保存在文件里
HDF5:适合复杂结构化数据
HDF5有点像一个小型数据库。它支持分层存储,一个文件里可以放多个数据集。比如你可以把股票数据、因子数据、回测结果都放在同一个HDF5文件里,用不同的key来区分。
不过说实话,在量化领域,HDF5的使用场景在减少。Parquet越来越成为主流。我只有在做高频数据存储时才会考虑HDF5,因为它对时间序列的切片操作支持得更好。
3.2 格式对比:一张表说清楚
| 特性 | CSV | Parquet | HDF5 |
|---|---|---|---|
| 存储方式 | 行式 | 列式 | 分层 |
| 压缩率 | 低 | 高 | 中 |
| 读取速度 | 慢 | 快 | 中 |
| 跨平台 | 极好 | 好 | 一般 |
| 适用场景 | 小数据、临时分析 | 大数据、因子测试 | 复杂结构化数据 |
3.3 Pandas DataFrame基础操作
不管用什么格式存数据,最终我们都要用Pandas来操作。DataFrame是Pandas的核心数据结构,说白了就是一个带标签的二维表格。
读取数据
import pandas as pd
# 读取CSV
df_csv = pd.read_csv('stock_data.csv')
# 读取Parquet
df_pq = pd.read_parquet('stock_data.parquet')
# 读取HDF5
df_h5 = pd.read_hdf('stock_data.h5', key='data')
嗯,这里要注意:读取Parquet需要安装pyarrow或fastparquet。我建议用pyarrow,性能更好。
数据预览与基本信息
# 看前5行
df.head()
# 看数据概览
df.info()
# 看统计描述
df.describe()
我个人习惯拿到数据后先跑一遍df.info()。它能告诉你每列的数据类型、非空值数量。我曾经有一次发现某列数据全是object类型,结果发现是日期格式没处理好,差点把整个因子计算带偏。
选择与过滤
# 选择单列
df['close']
# 选择多列
df[['close', 'volume']]
# 条件过滤
df[df['close'] > 100]
# 多条件
df[(df['close'] > 100) & (df['volume'] > 1000000)]
缺失值处理
真实数据里,缺失值太常见了。停牌、数据延迟、节假日,都会导致缺失。
# 检查缺失值
df.isnull().sum()
# 删除缺失值
df.dropna()
# 填充缺失值
df.fillna(method='ffill') # 用前一个值填充
df.fillna(0) # 用0填充
我个人建议:对于时间序列数据,用前向填充(ffill)比较合理。比如某只股票停牌一天,用前一天的收盘价填充,比用0要靠谱得多。
数据排序与重命名
# 按日期排序
df.sort_values('date')
# 重命名列
df.rename(columns={'close': '收盘价', 'volume': '成交量'})
3.4 知识体系总览
下面这张图,把本章的核心逻辑串起来了。你可以把它当作一个快速索引。
3.5 实战建议
最后给你几个实操建议:
- 日常分析用CSV:方便查看,方便分享。但记得定期清理,别让CSV文件堆成山。
- 因子测试用Parquet:速度快,省空间。我所有因子库都存成Parquet格式。
- 备份用HDF5:如果你需要保存多个版本的数据集,HDF5的分层结构很合适。
- 养成好习惯:每次读取数据后,先跑
df.info()和df.isnull().sum(),确认数据没问题再往下走。