现在位置: 首页 > Pandas 教程 > 正文

Pandas df.to_parquet() 函数

Pandas 常用函数 Pandas 常用函数


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, ...)

参数说明

参数类型说明默认值
pathstr, path object文件路径必填
enginestr引擎:'auto', 'pyarrow', 'fastparquet''auto'
compressionstr压缩方式:'snappy', 'gzip', 'brotli', None'snappy'
indexbool, None是否包含索引None
partition_colslist分区列,按列分区存储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)

运行结果:

已导出到 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

运行结果:

不同压缩方式的文件大小对比:
  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}')

运行结果:

已按 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'))

运行结果:

导出(默认包含索引)
导出(不包含索引)
导出(显式包含索引)

读取并比较差异:

原始数据:
    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() 需要安装 pyarrowfastparquet
  • 推荐安装 pyarrowpip install pyarrow
  • Parquet 是列式存储,适合大数据分析场景,不适合小数据。
  • 分区存储可以显著提高大数据查询性能。
  • Parquet 支持复杂数据类型(嵌套结构),但 pandas DataFrame 不常用。

小结

to_parquet() 是 DataFrame 导出为 Parquet 格式的方法。Parquet 是大数据领域的标准列式存储格式,具有高压缩比、高性能、支持分区等优点。

在大数据处理场景中,Parquet 是首选的数据格式。它与 Apache Spark、Apache Hive 等大数据框架完美兼容。如果处理大规模数据,建议使用 Parquet 格式替代 CSV 或 Excel。

Pandas 常用函数 Pandas 常用函数