Pandas df.to_parquet() 函数
to_parquet() 是 DataFrame 的方法,用于将数据导出为 Parquet 格式的文件。
Parquet 是一种列式存储的文件格式,专门为大数据分析场景设计。它具有高压缩比、高读写性能、支持复杂数据类型等优点,是 Apache Hadoop、Apache Spark 等大数据框架的标准格式。
基本语法与参数
语法格式
DataFrame.to_parquet(path, engine='auto', compression='snappy',
index=None, partition_cols=None, storage_options=None, ...)
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| path | str, path object | 文件路径 | 必填 |
| engine | str | 引擎:'auto', 'pyarrow', 'fastparquet' | 'auto' |
| compression | str | 压缩方式:'snappy', 'gzip', 'brotli', None | 'snappy' |
| index | bool, None | 是否包含索引 | None |
| partition_cols | list | 分区列,按列分区存储 | None |
返回值说明
- 返回类型:
None - 直接将数据写入 Parquet 文件,无返回值。
实例
通过以下示例,全面掌握 to_parquet() 的各种用法。
示例 1:基础用法 - 导出为 Parquet 文件
首先创建一个 DataFrame,然后使用 to_parquet() 导出为 Parquet 文件。
实例
import pandas as pd
# 创建一个示例 DataFrame
data = {
'name': ['Tom', 'Jerry', 'Mike', 'Lucy', 'John'],
'age': [28, 35, 42, 26, 31],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou'],
'salary': [8000, 12000, 15000, 7000, 9000],
'department': ['IT', 'HR', 'Sales', 'IT', 'HR']
}
df = pd.DataFrame(data)
# 示例 1a: 基本的导出
# path: 文件路径(必填)
# 默认使用 snappy 压缩
df.to_parquet('employees.parquet')
print("已导出到 employees.parquet")
# 查看文件大小
import os
file_size = os.path.getsize('employees.parquet')
print(f"文件大小: {file_size} 字节")
# 示例 1b: 读取验证
# 需要安装 pyarrow 或 fastparquet
df_check = pd.read_parquet('employees.parquet')
print("n验证读取:")
print(df_check)
# 创建一个示例 DataFrame
data = {
'name': ['Tom', 'Jerry', 'Mike', 'Lucy', 'John'],
'age': [28, 35, 42, 26, 31],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou'],
'salary': [8000, 12000, 15000, 7000, 9000],
'department': ['IT', 'HR', 'Sales', 'IT', 'HR']
}
df = pd.DataFrame(data)
# 示例 1a: 基本的导出
# path: 文件路径(必填)
# 默认使用 snappy 压缩
df.to_parquet('employees.parquet')
print("已导出到 employees.parquet")
# 查看文件大小
import os
file_size = os.path.getsize('employees.parquet')
print(f"文件大小: {file_size} 字节")
# 示例 1b: 读取验证
# 需要安装 pyarrow 或 fastparquet
df_check = pd.read_parquet('employees.parquet')
print("n验证读取:")
print(df_check)
运行结果:
已导出到 employees.parquet
文件大小: 约 600-800 字节(远小于 CSV)
验证读取:
name age city salary department
0 Tom 28 Beijing 8000 IT
1 Jerry 35 Shanghai 12000 HR
2 Mike 42 Guangzhou 15000 Sales
3 Lucy 26 Shenzhen 7000 IT
4 John 31 Hangzhou 9000 HR
代码解析:
to_parquet()将 DataFrame 导出为 Parquet 格式。- 默认使用
snappy压缩,压缩效果显著。 - Parquet 文件比 CSV 文件小很多,读取速度也更快。
示例 2:选择引擎和压缩方式
Parquet 格式支持多种引擎和压缩方式,可以根据需求选择。
实例
import pandas as pd
import os
# 创建更大的 DataFrame 以观察压缩效果
import numpy as np
np.random.seed(42)
df_large = pd.DataFrame({
'id': range(10000),
'value': np.random.randn(10000),
'category': np.random.choice(['A', 'B', 'C', 'D'], 10000),
'name': np.random.choice(['Tom', 'Jerry', 'Mike', 'Lucy', 'John'], 10000)
})
# 示例 2a: 使用不同的压缩方式
# snappy: 快速压缩,速度快,压缩比适中(默认)
df_large.to_parquet('output_snappy.parquet', compression='snappy')
# gzip: 高压缩比,文件更小
df_large.to_parquet('output_gzip.parquet', compression='gzip')
# brotli: 更高的压缩比
df_large.to_parquet('output_brotli.parquet', compression='brotli')
# 无压缩
df_large.to_parquet('output_none.parquet', compression=None)
# 比较文件大小
print("不同压缩方式的文件大小对比:")
for name in ['snappy', 'gzip', 'brotli', 'none']:
size = os.path.getsize(f'output_{name}.parquet')
print(f" {name}: {size:,} 字节")
print()
# 示例 2b: 选择引擎
# auto: 自动选择(默认)
# pyarrow: Apache Arrow 的实现,功能完整,性能好
# fastparquet: 纯 Python 实现,兼容性好
print("可用引擎: auto, pyarrow, fastparquet")
print("当前使用:", end=" ")
# 检查可用的引擎
try:
import pyarrow
print("pyarrow")
except ImportError:
pass
try:
import fastparquet
print("fastparquet")
except ImportError:
pass
import os
# 创建更大的 DataFrame 以观察压缩效果
import numpy as np
np.random.seed(42)
df_large = pd.DataFrame({
'id': range(10000),
'value': np.random.randn(10000),
'category': np.random.choice(['A', 'B', 'C', 'D'], 10000),
'name': np.random.choice(['Tom', 'Jerry', 'Mike', 'Lucy', 'John'], 10000)
})
# 示例 2a: 使用不同的压缩方式
# snappy: 快速压缩,速度快,压缩比适中(默认)
df_large.to_parquet('output_snappy.parquet', compression='snappy')
# gzip: 高压缩比,文件更小
df_large.to_parquet('output_gzip.parquet', compression='gzip')
# brotli: 更高的压缩比
df_large.to_parquet('output_brotli.parquet', compression='brotli')
# 无压缩
df_large.to_parquet('output_none.parquet', compression=None)
# 比较文件大小
print("不同压缩方式的文件大小对比:")
for name in ['snappy', 'gzip', 'brotli', 'none']:
size = os.path.getsize(f'output_{name}.parquet')
print(f" {name}: {size:,} 字节")
print()
# 示例 2b: 选择引擎
# auto: 自动选择(默认)
# pyarrow: Apache Arrow 的实现,功能完整,性能好
# fastparquet: 纯 Python 实现,兼容性好
print("可用引擎: auto, pyarrow, fastparquet")
print("当前使用:", end=" ")
# 检查可用的引擎
try:
import pyarrow
print("pyarrow")
except ImportError:
pass
try:
import fastparquet
print("fastparquet")
except ImportError:
pass
运行结果:
不同压缩方式的文件大小对比: snappy: 约 100KB gzip: 约 80KB brotli: 约 70KB none: 约 200KB 不同压缩方式各有优劣: snappy: 速度快,压缩比适中(默认推荐) gzip: 压缩比更高,适合存储 brotli: 最高压缩比,适合冷数据 none: 无压缩,速度最快
代码解析:
compression参数可以选择不同的压缩方式。snappy是默认选项,平衡了速度和压缩比。gzip压缩比更高,但速度稍慢。engine参数可以选择使用哪个引擎。
示例 3:分区存储
Parquet 支持按列分区存储,这是大数据分析中的重要特性。
实例
import pandas as pd
import os
import shutil
# 创建 DataFrame
df = pd.DataFrame({
'name': ['Tom', 'Jerry', 'Mike', 'Lucy', 'John', 'Mary', 'Bob', 'Alice'],
'age': [28, 35, 42, 26, 31, 29, 38, 24],
'department': ['IT', 'HR', 'Sales', 'IT', 'HR', 'IT', 'Sales', 'HR'],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou',
'Beijing', 'Shanghai', 'Beijing']
})
# 示例 3a: 按单列分区
# partition_cols 指定分区列,会生成子目录
if os.path.exists('partitioned'):
shutil.rmtree('partitioned')
df.to_parquet('partitioned', partition_cols=['department'])
print("已按 department 分区导出")
# 查看分区目录结构
for root, dirs, files in os.walk('partitioned'):
level = root.replace('partitioned', '').count(os.sep)
indent = ' ' * 2 * level
print(f'{indent}{os.path.basename(root)}/')
subindent = ' ' * 2 * (level + 1)
for file in files:
print(f'{subindent}{file}')
import os
import shutil
# 创建 DataFrame
df = pd.DataFrame({
'name': ['Tom', 'Jerry', 'Mike', 'Lucy', 'John', 'Mary', 'Bob', 'Alice'],
'age': [28, 35, 42, 26, 31, 29, 38, 24],
'department': ['IT', 'HR', 'Sales', 'IT', 'HR', 'IT', 'Sales', 'HR'],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou',
'Beijing', 'Shanghai', 'Beijing']
})
# 示例 3a: 按单列分区
# partition_cols 指定分区列,会生成子目录
if os.path.exists('partitioned'):
shutil.rmtree('partitioned')
df.to_parquet('partitioned', partition_cols=['department'])
print("已按 department 分区导出")
# 查看分区目录结构
for root, dirs, files in os.walk('partitioned'):
level = root.replace('partitioned', '').count(os.sep)
indent = ' ' * 2 * level
print(f'{indent}{os.path.basename(root)}/')
subindent = ' ' * 2 * (level + 1)
for file in files:
print(f'{subindent}{file}')
运行结果:
已按 department 分区导出
分区目录结构:
partitioned/
department=HR/
xxx.parquet
department=IT/
xxx.parquet
department=Sales/
xxx.parquet
代码解析:
partition_cols参数按指定列进行分区存储。- 分区存储会在文件系统中创建子目录,每个分区值一个目录。
- 分区存储对大数据查询非常有利,可以只读取需要的分区。
示例 4:处理索引
Parquet 导出时可以选择是否包含索引。
实例
import pandas as pd
# 创建带索引的 DataFrame
df = pd.DataFrame({
'name': ['Tom', 'Jerry', 'Mike', 'Lucy'],
'age': [28, 35, 42, 26],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen']
})
df.index = ['A001', 'A002', 'A003', 'A004']
# 示例 4a: 默认包含索引
df.to_parquet('with_index.parquet')
print("导出(默认包含索引)")
# 示例 4b: 不包含索引
df.to_parquet('without_index.parquet', index=False)
print("导出(不包含索引)")
# 示例 4c: 显式包含索引
df.to_parquet('explicit_index.parquet', index=True)
print("导出(显式包含索引)")
# 读取并比较
print("n读取并比较差异:")
print("n原始数据:")
print(df)
print("n读取 with_index.parquet:")
print(pd.read_parquet('with_index.parquet'))
print("n读取 without_index.parquet:")
print(pd.read_parquet('without_index.parquet'))
print("n读取 explicit_index.parquet:")
print(pd.read_parquet('explicit_index.parquet'))
# 创建带索引的 DataFrame
df = pd.DataFrame({
'name': ['Tom', 'Jerry', 'Mike', 'Lucy'],
'age': [28, 35, 42, 26],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen']
})
df.index = ['A001', 'A002', 'A003', 'A004']
# 示例 4a: 默认包含索引
df.to_parquet('with_index.parquet')
print("导出(默认包含索引)")
# 示例 4b: 不包含索引
df.to_parquet('without_index.parquet', index=False)
print("导出(不包含索引)")
# 示例 4c: 显式包含索引
df.to_parquet('explicit_index.parquet', index=True)
print("导出(显式包含索引)")
# 读取并比较
print("n读取并比较差异:")
print("n原始数据:")
print(df)
print("n读取 with_index.parquet:")
print(pd.read_parquet('with_index.parquet'))
print("n读取 without_index.parquet:")
print(pd.read_parquet('without_index.parquet'))
print("n读取 explicit_index.parquet:")
print(pd.read_parquet('explicit_index.parquet'))
运行结果:
导出(默认包含索引)
导出(不包含索引)
导出(显式包含索引)
读取并比较差异:
原始数据:
name age city
A001 Tom 28 Beijing
A002 Jerry 35 Shanghai
A003 Mike 42 Guangzhou
A004 Lucy 26 Shenzhen
读取 with_index.parquet:
name age city index
0 Tom 28 Beijing A001
1 Jerry 35 Shanghai A002
2 Mike 42 Guangzhou A003
3 Lucy 26 Shenzhen A004
读取 without_index.parquet:
name age city
0 Tom 28 Beijing
1 Jerry 35 Shanghai
2 Mike 42 Guangzhou
3 Lucy 26 Shenzhen
读取 explicit_index.parquet:
name age city index
0 Tom 28 Beijing A001
1 Jerry 35 Shanghai A002
2 Mike 42 Guangzhou A003
3 Lucy 26 Shenzhen A004
代码解析:
index=True显式包含索引作为一列。index=False不包含索引。- 默认行为取决于 pandas 的索引设置。
注意事项
- 使用
to_parquet()需要安装pyarrow或fastparquet。 - 推荐安装
pyarrow:pip install pyarrow。 - Parquet 是列式存储,适合大数据分析场景,不适合小数据。
- 分区存储可以显著提高大数据查询性能。
- Parquet 支持复杂数据类型(嵌套结构),但 pandas DataFrame 不常用。
小结
to_parquet() 是 DataFrame 导出为 Parquet 格式的方法。Parquet 是大数据领域的标准列式存储格式,具有高压缩比、高性能、支持分区等优点。
在大数据处理场景中,Parquet 是首选的数据格式。它与 Apache Spark、Apache Hive 等大数据框架完美兼容。如果处理大规模数据,建议使用 Parquet 格式替代 CSV 或 Excel。

Pandas 常用函数