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

如何进一步压缩Tick数据文件大小?

Tick数据压缩的进一步优化方案

当前实现情况

我正在处理Tick数据压缩工作,目前已通过delta编码+ZSTD压缩的Parquet存储将4个月的数据从150MB降至66MB,但随着数据积累仍会面临体积膨胀问题。已测试多种压缩方案(hdf5_blosc、hdf5_gzip、feather_lz4、parquet_lz4、parquet_snappy、parquet_zstd、feather_zstd、parquet_gzip、parquet_brotli),确认ZSTD对当前数据的存储效率最高。

当前代码实现

Delta编码逻辑

def apply_delta_encoding(df: pd.DataFrame) -> pd.DataFrame:
    df = df.copy()

    # Convert datetime index to Unix timestamp in milliseconds
    df['timestamp'] = df.index.astype('int64') // 1_000_000

    # Keep the first row unchanged for delta encoding
    for col in df.columns:
        if col != 'timestamp':  # Skip timestamp column
            df[col] = df[col].diff().fillna(df[col].iloc[0]).astype("float32")

    return df

数据保存逻辑

df.to_parquet(self.file_path, index=False, compression='zstd', compression_level=22)

示例Tick数据

bid           ask
datetime
2025-03-27 00:00:00.034  86752.601562  86839.500000
2025-03-27 00:00:01.155  86760.468750  86847.390625
2025-03-27 00:00:01.357  86758.992188  86845.914062
2025-03-27 00:00:09.518  86749.804688  86836.703125
2025-03-27 00:00:09.782  86741.601562  86828.500000

进一步压缩的优化技巧

1. 对时间戳应用Delta编码

当前仅对bid/ask字段做了delta编码,时间戳同样可以采用该方式:

  • 保留第一个时间戳的原始值,后续存储与前一个时间戳的差值
  • 时间戳差值的数值范围远小于原始Unix时间戳,能大幅提升压缩率
  • 解码时只需累加差值即可恢复完整时间序列

修改后的编码逻辑示例:

def apply_full_delta_encoding(df: pd.DataFrame) -> pd.DataFrame:
    df = df.copy()
    # 转换为毫秒级时间戳
    df['timestamp'] = df.index.astype('int64') // 1_000_000
    # 对时间戳做delta编码
    df['timestamp'] = df['timestamp'].diff().fillna(df['timestamp'].iloc[0])
    # 对bid/ask做delta编码
    for col in ['bid', 'ask']:
        df[col] = df[col].diff().fillna(df[col].iloc[0]).astype("float32")
    return df

2. 优化数据类型精度

  • 数值字段优化:若业务允许,可将bid/ask的差值转换为整数类型(比如乘以1000后转int32),整数比浮点数更易压缩,解码时再除以对应倍数即可
    示例:df[col] = (df[col].diff().fillna(df[col].iloc[0]) * 1000).astype("int32")
  • 时间戳优化:毫秒级时间戳的差值用int32足够覆盖(最大可表示约24天的差值),无需使用int64

3. Parquet文件的分区与分块优化

  • 按时间分区:将数据按天/周拆分为多个Parquet文件,而非单文件存储,列存储特性在分区后能更高效压缩
  • 调整Row Group大小:通过row_group_size参数设置合适的行组大小(比如10万行),让压缩算法能利用更大的上下文提升压缩率

修改保存代码示例:

df.to_parquet(
    self.file_path,
    index=False,
    compression='zstd',
    compression_level=22,
    row_group_size=100000  # 根据数据量调整
)

4. 高级预编码技巧

  • Run-Length Encoding (RLE):如果存在连续相同的差值(比如价格不变的场景),可先对差值做RLE编码再交给ZSTD压缩,Parquet本身支持RLE,但手动预处理可进一步优化
  • 显式开启字典编码:对重复出现的差值做字典映射,可通过use_dictionary=True参数强制开启,提升重复值的压缩效率

5. 列级混合压缩策略

对不同列采用针对性的压缩算法:比如时间戳差值用LZ4(速度快且压缩率足够),bid/ask差值用ZSTD(更高压缩率),Parquet支持为每列单独设置压缩方式

示例:

from pyarrow import parquet as pq
import pyarrow as pa

table = pa.Table.from_pandas(df)
# 为不同列设置不同压缩方案
compression_options = {
    'timestamp': 'lz4',
    'bid': 'zstd',
    'ask': 'zstd'
}
pq.write_table(
    table,
    self.file_path,
    compression=compression_options,
    compression_level=22
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:37:24