推荐可存储多异构Pandas DataFrame的单文件二进制格式
问题背景
我有大约200个结构完全不同的Pandas DataFrame(部分列唯一,Schema差异大),示例如下:
import pandas as pd df1 = pd.DataFrame({ 'Product': ['Apple', 'Banana', 'Orange', 'Mango'], 'Quantity': [10, 15, 12, 8], 'Price': [2.5, 1.5, 2, 3], 'Category': ['Fruit', 'Fruit', 'Fruit', 'Fruit'] }) df2 = pd.DataFrame({ 'Student Name': ['John', 'Emma', 'Lisa', 'Tom'], 'Age': [18, 17, 19, 18], 'Grade': ['A', 'B', 'A', 'B'], 'City': ['New York', 'London', 'Paris', 'Sydney'] }) df3 = pd.DataFrame({ 'Date': ['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04'], 'Company': ['AAPL', 'GOOG', 'AMZN', 'MSFT'], 'Price': [132.69, 1760.33, 3187.50, 215.41] }) # 更多结构不同的DataFrame
原本计划用Parquet存储到同一文件夹,但不确定不同Schema的Parquet文件是否可行,现咨询:
- 除Excel外,有哪些可将多个DataFrame存储在单个文件中的格式?
- ORC格式的
to_orc()能否处理不同Schema的DataFrame合并存储,以及NA值的处理?
一、支持多Schema单文件存储的格式
以下是几种适合的格式,均支持将不同Schema的DataFrame存储在单个文件中:
HDF5
Pandas原生支持的格式,通过pd.HDFStore可以将不同Schema的DataFrame作为独立的键(表)存入同一个.h5文件,支持高效的索引、查询和增量写入,NA值处理完全兼容。
# 写入 with pd.HDFStore('multi_dfs.h5') as store: store['df1'] = df1 store['df2'] = df2 store['df3'] = df3 # 读取 with pd.HDFStore('multi_dfs.h5') as store: df1 = store['df1'] df2 = store['df2']
SQLite
将每个DataFrame作为独立表存入单个SQLite数据库文件,支持SQL查询,NA值会被自动映射为SQL的NULL,读取时可还原为Pandas的NA。
import sqlite3 # 写入 conn = sqlite3.connect('multi_dfs.db') df1.to_sql('df1', conn, if_exists='replace', index=False) df2.to_sql('df2', conn, if_exists='replace', index=False) conn.close() # 读取 conn = sqlite3.connect('multi_dfs.db') df1 = pd.read_sql('SELECT * FROM df1', conn) conn.close()
ZIP压缩包(内含多份Parquet/CSV)
将不同Schema的DataFrame分别保存为Parquet/CSV文件,再打包成单个ZIP文件。Pandas可以直接读取ZIP内的文件,兼顾存储效率和单文件管理需求。
import zipfile # 写入 with zipfile.ZipFile('multi_dfs.zip', 'w') as zf: # 写入Parquet到压缩包 df1.to_parquet(zf.open('df1.parquet'), index=False) df2.to_parquet(zf.open('df2.parquet'), index=False) # 读取 df1 = pd.read_parquet('multi_dfs.zip/df1.parquet')
Apache Arrow IPC 文件
通过PyArrow库可以将多个不同Schema的表写入单个Arrow IPC文件,支持高效的列存和跨语言访问,NA值处理原生兼容。
import pyarrow as pa import pyarrow.ipc as ipc # 将DataFrame转为Arrow表 tables = [pa.Table.from_pandas(df) for df in [df1, df2, df3]] # 写入单个IPC文件 with ipc.new_file('multi_tables.arrow', tables[0].schema) as writer: for table in tables: writer.write_table(table) # 读取 with ipc.open_file('multi_tables.arrow') as reader: df1 = reader.read_table(0).to_pandas() df2 = reader.read_table(1).to_pandas()
二、ORC格式的相关问题
多Schema支持
ORC单个文件仅支持单一Schema,Pandas的to_orc()方法只能写入单个DataFrame到一个ORC文件,无法直接将不同Schema的DataFrame合并存储。如果需要用ORC存储,必须先将所有DataFrame统一Schema(缺失列补NA),再写入单个ORC文件,但这会破坏原始DataFrame的结构独立性。
NA值处理
ORC原生支持NULL值,Pandas的NA值会被正确映射为ORC的NULL,读取时可完整还原为Pandas的NA,NA值处理无问题。
内容的提问来源于stack exchange,提问作者Abdulrahman Sheikho

