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

含列表列的800万行Pandas DataFrame如何保存为HDF格式?

解决含列表列的Pandas DataFrame保存为HDF格式的问题

这个报错本质上是因为HDFStore默认的fixed格式(也就是store.append或store.put默认的格式)对object dtype里的复杂结构(比如列表)兼容性不好——它更适合存储基础数据类型(数值、字符串等)。针对你的800万行大DF+按需查询的需求,这里有几个可行的方案:


方案1:将列表列序列化为JSON字符串(通用兼容)

把列表转成JSON字符串,这样列的dtype变成字符串,HDF就能正常存储了。读取的时候再解析回列表即可。

示例代码:

import pandas as pd
import json

# 假设你的DF是df,列表列名为'list_col'
df['list_col'] = df['list_col'].apply(json.dumps)

# 保存为HDF,用table格式支持后续按需筛选
with pd.HDFStore('large_data.h5', mode='w') as store:
    store.put('my_df', df, format='table')

# 读取时解析回列表
with pd.HDFStore('large_data.h5', mode='r') as store:
    loaded_df = store.get('my_df')
loaded_df['list_col'] = loaded_df['list_col'].apply(json.loads)

优缺点:

  • 优点:完全兼容所有列表结构(不管长度是否固定),不改变原数据结构;table格式支持后续用where参数按需筛选数据,节省内存。
  • 缺点:序列化/反序列化会带来一定性能开销,800万行需要留出足够处理时间;字符串存储的体积可能比原列表略大,但相比加载全量DF还是划算的。

方案2:使用HDF的table格式直接存储(简化操作)

HDF的table格式(行式存储)比默认的fixed格式(列式存储)支持更灵活的object dtype,很多情况下直接用它就能解决列表列的存储问题,无需额外序列化。

示例代码:

import pandas as pd

# 直接用table格式保存,data_columns=True为常用列建索引,加速查询
with pd.HDFStore('large_data.h5', mode='w') as store:
    store.put('my_df', df, format='table', data_columns=True)

# 按需读取筛选后的数据(比如筛选某列值为X的行)
with pd.HDFStore('large_data.h5', mode='r') as store:
    filtered_df = store.get('my_df', where="some_column == 'X'")

注意事项:

  • 确保你的Pandas版本不是太老(建议0.24+),老版本对object dtype的table格式支持可能有bug。
  • 如果列表里包含非常特殊的对象(比如自定义类实例),这个方法可能还是会报错,此时方案1更稳妥。

方案3:拆分列表列为多列(适合固定长度的列表)

如果你的列表列里每个列表的长度是固定的(比如每个列表都有3个元素),可以直接把列表拆分成多个独立的列,这样所有列都是基础数据类型,HDF存储毫无压力,查询性能也最优。

示例代码:

import pandas as pd

# 假设列表列每个元素都是长度为3的列表
df[['col_1', 'col_2', 'col_3']] = pd.DataFrame(df['list_col'].tolist(), index=df.index)
df = df.drop('list_col', axis=1)

# 保存为HDF,fixed格式性能更好
with pd.HDFStore('large_data.h5', mode='w') as store:
    store.put('my_df', df, format='fixed')

优缺点:

  • 优点:存储和查询性能最优,完全避免object dtype的问题。
  • 缺点:只适用于列表长度固定的场景;如果后续列表长度变化,维护成本很高。

额外小贴士

  • 测试时先拿一小部分数据(比如1000行)验证方案可行性,避免直接处理800万行出问题浪费时间。
  • 如果你的按需查询频率很高,建议把常用的筛选列设置为data_columns=True(在store.put时指定),这样HDF会为这些列建立索引,查询速度会快很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:35:53