Parquet:高速列式存储
使用 to_parquet() 将 Pandas DataFrame 写入 Parquet,以比 CSV 更快的速度读回,并使用列裁剪只加载所需字段。
Parquet:高速列式存储 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。
Parquet 是什么
Apache Parquet 是一种面向分析工作负载设计的列式二进制文件格式。CSV 会将数据按行以文本形式存储,而 Parquet 会将每一列存储在连续的数据块中,对其进行高效压缩,并编码元数据。因此,对于只读取宽表中少数几列的查询,Parquet 的速度会快得多。Parquet 是数据湖事实上的标准格式(AWS S3、Google Cloud Storage),并且受到 Pandas、Dask、Spark 和 BigQuery 的原生支持。
使用 to_parquet() 写入 Parquet
将 Pandas DataFrame 转换为 Parquet 只需调用一次方法:df.to_parquet('output.parquet')。默认引擎是 pyarrow(使用 pip install pyarrow 安装)。Parquet 会准确保留列的数据类型——日期列不再被读回为字符串。它还通过 compression 参数直接支持压缩;'snappy' 读写速度快且压缩程度适中,而 'gzip' 压缩率更高,但速度会有所降低。
import pandas as pd
import numpy as np
# Create a sample DataFrame
np.random.seed(0)
df = pd.DataFrame({
'date': pd.date_range('2024-01-01', periods=100000, freq='T'),
'value': np.random.randn(100000),
'category': np.random.choice(['A', 'B', 'C'], 100000)
})
# Write to Parquet
df.to_parquet('data.parquet', index=False, compression='snappy')
print('Written to data.parquet')使用 read_parquet() 读取 Parquet
pd.read_parquet('output.parquet') 会将文件读回 DataFrame。与读取等价的 CSV 文件相比,对于包含许多列的宽表,Parquet 的读取速度通常快 5 到 10 倍。数据类型会被准确保留——日期仍为 datetime64,分类数据仍为 category,整数则按照存储方式保持为 int32 或 int64。由于元数据已嵌入文件,因此不需要推断数据类型。
import pandas as pd
import time
# Read Parquet
start = time.time()
df = pd.read_parquet('data.parquet')
print(f'Read Parquet: {time.time()-start:.3f}s')
print(df.dtypes)
print(df.shape)列裁剪:只读取所需的列
列式存储最大的优势是列裁剪:您可以只读取指定的列,而无需扫描文件的其余部分。将列名列表传递给 columns 参数即可。如果一个包含 100 列的表中每列占用 100 MB,而您只需要其中 3 列,Parquet 只需读取 3 MB,而不是 10 GB。CSV 必须扫描每个字符才能提取任意列。因此,Parquet 非常适合数据分析管道中的宽表。
import pandas as pd
# Only load the 2 columns needed for this analysis
df = pd.read_parquet('large_table.parquet',
columns=['date', 'revenue'])
print(df.columns.tolist())
print(df.shape)
print(df.memory_usage(deep=True).sum() / 1e6, 'MB loaded')行组筛选(谓词下推)
Parquet 会在文件尾部为每个行组(一组数据行)存储统计信息(最小值/最大值)。当您通过 filters 参数应用筛选条件时,读取器会跳过整个筛选条件不可能匹配的行组——这称为谓词下推。例如,在按时间排序的 Parquet 文件中筛选日期时,读取器会跳过超出范围的整个月份数据块,只读取相关部分。pyarrow 引擎原生支持此功能。
import pandas as pd
# Filter using predicate pushdown — row groups outside range are skipped
df = pd.read_parquet(
'time_series.parquet',
columns=['date', 'value'],
filters=[('date', '>=', '2024-06-01'),
('date', '<', '2024-07-01')]
)
print(f'Loaded {len(df):,} rows (June only)')
print(df.head())Parquet 与 CSV:对比
下面以一个包含 1000 万行、20 列的数据集为例,对 Parquet 和 CSV 进行实际比较:
- 文件大小:CSV 约 2 GB,Parquet(snappy)约 400 MB
- 读取时间(所有列):CSV 约 15 秒,Parquet 约 2 秒
- 读取时间(3 列):CSV 约 15 秒(必须扫描全部内容),Parquet 约 0.3 秒
- 数据类型保留:CSV 会丢失数据类型,Parquet 会保留数据类型
- 可读性:CSV 是,Parquet 否(二进制格式)
对于只写入一次、却需要读取多次的生产数据管道,Parquet 几乎总是更好的选择。
分区式 Parquet 数据集
对于非常大的数据集,Parquet 支持分区式数据集:数据会按列值组织到目录层次结构中,并拆分为多个文件。例如,按年份和月份分区会创建 data/year=2024/month=01/part.parquet。读取分区式数据集时,会自动筛选与查询匹配的目录。这是数据湖中的标准布局,并支持对数十亿行数据进行高效的范围查询。
import pandas as pd
# Write a partitioned dataset (requires pyarrow)
df = pd.read_parquet('all_data.parquet')
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df.to_parquet(
'partitioned_data/',
partition_cols=['year', 'month'],
index=False
)
# Creates: partitioned_data/year=2024/month=1/part-0.parquet etc.读取分区式数据集
读取分区式 Parquet 目录与读取单个文件完全相同——Pandas(通过 pyarrow)会自动发现所有分区文件。分区列的值会作为列包含在生成的 DataFrame 中。您还可以使用 filters 来利用分区裁剪,根据分区列的值跳过整个目录子树。这样,查询 1 TB 的分区式数据集就像读取几 MB 的数据一样轻松。
import pandas as pd
# Read the entire partitioned dataset
df_all = pd.read_parquet('partitioned_data/')
print('All years:', df_all['year'].unique())
# Read only 2024 data using partition pruning
df_2024 = pd.read_parquet(
'partitioned_data/',
filters=[('year', '==', 2024)]
)
print('2024 rows:', len(df_2024))使用 Dask 处理 Parquet
Dask 通过 dd.read_parquet() 和 ddf.to_parquet() 原生支持 Parquet 的读写。分区式 Parquet 目录中的每个文件都会成为一个 Dask 分区,从而支持完全并行的读取。指定筛选条件时,Dask 还会利用谓词下推。将大型 Dask 结果写入分区式 Parquet 数据集,是现代数据工程管道生成输出的标准方式。
import dask.dataframe as dd
# Read partitioned Parquet with Dask (each file = one partition)
ddf = dd.read_parquet('partitioned_data/',
columns=['date', 'revenue', 'region'],
filters=[('year', '==', 2024)])
# Compute aggregation in parallel
result = ddf.groupby('region')['revenue'].sum().compute()
print(result.sort_values(ascending=False))压缩与编码选项
Parquet 支持多种压缩算法和内部编码方案。Snappy(默认)优先考虑速度,提供适度的压缩效果。Gzip 可将文件压缩得小约 30%,但读写速度较慢。Zstd 在速度和压缩效果之间取得了比前两者更好的平衡。对于整数列,Parquet 会自动应用增量编码或字典编码,无需您进行额外配置即可进一步减小文件大小。
import pandas as pd
import numpy as np
np.random.seed(0)
df = pd.DataFrame({'id': range(500000), 'val': np.random.randn(500000)})
for comp in ['snappy', 'gzip', 'zstd']:
fname = f'data_{comp}.parquet'
df.to_parquet(fname, compression=comp, index=False)
import os
size_mb = os.path.getsize(fname) / 1e6
print(f'{comp}: {size_mb:.2f} MB')在数据处理中替换 CSV
采用 Parquet 最简单的方法,是在项目开始时加入一个一次性转换步骤:读取一次 CSV,清理数据并转换数据类型,然后保存为 Parquet。之后的所有运行都读取 Parquet 文件,而不是 CSV。这样只需极少的代码改动,就能立即获得速度和存储方面的优势。对于以 CSV 格式到达的新数据(例如每晚导出的数据),请在数据处理流程中加入转换步骤,在任何分析开始前先将其写入 Parquet。
import pandas as pd
# One-time conversion
df = pd.read_csv('raw_data.csv',
parse_dates=['date'],
dtype={'category': 'category',
'amount': 'float32'})
df.to_parquet('clean_data.parquet', index=False)
# All future reads use Parquet
df_fast = pd.read_parquet('clean_data.parquet')
print('Loaded from Parquet:', df_fast.dtypes.to_dict())快速检查
测试您对本课数据分析概念的理解。
课程回顾
在本课中,您学会了:与 CSV 相比,to_parquet() 和 read_parquet() 能提供更快、更小且保留数据类型的文件输入输出;使用 columns 参数进行列裁剪,只读取所需列,避免扫描整个文件;按列值组织的分区 Parquet 数据集支持分区裁剪,从而能在大型数据湖上高效执行范围查询。接下来,我们将使用 SQLAlchemy 将 Pandas 连接到关系数据库。
常见问题解答
「Parquet:高速列式存储」课时是免费的吗?
是的 — 「Parquet:高速列式存储」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。
「Parquet:高速列式存储」这节课中我会学到什么?
使用 to_parquet() 将 Pandas DataFrame 写入 Parquet,以比 CSV 更快的速度读回,并使用列裁剪只加载所需字段。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Pandas & NumPy Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「Parquet:高速列式存储」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?
能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 chunksize 流式读取 CSV
- 跨数据块增量聚合
- Dask DataFrames 入门
- Parquet:高速列式存储