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

Pandas导出Parquet适配Redshift外部表的PyArrow与fastparquet实现方案

我有一个非常简单的思路:出于便捷性考虑,使用Python Pandas对中等体量数据执行简单数据库操作后,将数据以Parquet格式回写到S3,再将该数据作为外部表挂载到Redshift,避免占用Redshift集群本身的存储空间。我找到了两种实现方案:


示例数据

示例测试数据构造代码如下:

from datetime import date, datetime
import pandas as pd

data = {
    'int': [1, 2, 3, 4, None],
    'float': [1.1, None, 3.4, 4.0, 5.5],
    'str': [None, 'two', 'three', 'four', 'five'],
    'boolean': [True, None, True, False, False],
    'date': [
        date(2000, 1, 1),
        date(2000, 1, 2),
        date(2000, 1, 3),
        date(2000, 1, 4),
        None,
    ],
    'timestamp': [
        datetime(2000, 1, 1, 1, 1, 1),
        datetime(2000, 1, 1, 1, 1, 2),
        None,
        datetime(2000, 1, 1, 1, 1, 4),
        datetime(2000, 1, 1, 1, 1, 5),
    ]
}

df = pd.DataFrame(data)

df['int'] = df['int'].astype(pd.Int64Dtype())
df['date'] = df['date'].astype('datetime64[D]')
df['timestamp'] = df['timestamp'].astype('datetime64[s]')

末尾的类型转换操作在两种方案中均为必要步骤,可避免Pandas自动类型识别产生干扰。

使用PyArrow实现

采用PyArrow的实现代码如下:

import pyarrow as pa

pyarrow_schema = pa.schema([
    ('int', pa.int64()),
    ('float', pa.float64()),
    ('str', pa.string()),
    ('bool', pa.bool_()),
    ('date', pa.date64()),
    ('timestamp', pa.timestamp(unit='s'))
])

df.to_parquet(
    path='pyarrow.parquet',
    schema=pyarrow_schema,
    engine='pyarrow'
)

PyArrow优势说明:Pandas导出Parquet的默认引擎为PyArrow,集成适配性好,同时功能丰富,支持的数据源类型非常全面。

使用fastparquet实现

使用fastparquet需要额外配置相关参数,导出代码如下:

from fastparquet import write

write('fast.parquet', df, has_nulls=True, times='int96')

这里的核心配置是times参数,我在fastparquet官方项目的issue讨论中找到了date字段适配问题的解决方案。
fastparquet优势说明:fastparquet相比PyArrow功能局限性更强,尤其是支持的数据类型更少,但对应的安装包体积要小很多。

创建Redshift外部表

完成Parquet文件导出并存入S3后,可通过以下SQL语句将数据挂载为Redshift外部表:

CREATE EXTERNAL TABLE "<your_external_schema>"."<your_table_name>" (
 "int" bigint,
 "float" float,
 "str" varchar(255),
 "boolean" bool,
 "date" date,
 "timestamp" timestamp)
 ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
location 
  's3://<your_bucket>/<your_prefix>/';
实践背景与注意事项

我最初在AWS Lambda函数场景中使用Pandas、Parquet和Redshift外部表时,初期运行一切正常,直到Lambda部署包体积达到了上限(参考AWS Lambda官方的部署包体积限制规则)。排查依赖体积后发现PyArrow、Pandas以及Pandas依赖的Numpy是体积占用的主要来源。由于不能为了性能舍弃Numpy,同时也不想放弃Pandas的便捷性,我便尝试寻找轻量的PyArrow替代方案,最终找到了fastparquet,经过调研和大量测试后成功实现了需求。
希望以上说明和相关资源能为其他开发者提供帮助。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:18:01