【问题标题】:How to write parquet file from pandas dataframe in S3 in python如何在 python 的 S3 中从 Pandas 数据帧写入镶木地板文件
【发布时间】:2019-04-24 06:26:00
【问题描述】:

我有一个熊猫数据框。我想将此数据框写入 S3 中的镶木地板文件。 我需要一个相同的示例代码。我试图用谷歌搜索它。但我无法获得有效的示例代码。

【问题讨论】:

    标签: python-3.x amazon-s3 parquet


    【解决方案1】:

    首先确保您已经安装了带有 pandas 的 pyarrow 或 fastparquet。

    然后安装 boto3 和 aws cli。使用 aws cli 设置位于 .aws 文件夹中的配置和凭据文件。

    这是一个简单的脚本,使用 pyarrowboto3 创建临时拼花文件,然后发送到 AWS S3。

    不包括导入的示例代码:

    def main():
        data = {0: {"data1": "value1"}}
        df = pd.DataFrame.from_dict(data, orient='index')
        write_pandas_parquet_to_s3(
            df, "bucket", "folder/test/file.parquet", ".tmp/file.parquet")
    
    
    def write_pandas_parquet_to_s3(df, bucketName, keyName, fileName):
        # dummy dataframe
        table = pa.Table.from_pandas(df)
        pq.write_table(table, fileName)
    
        # upload to s3
        s3 = boto3.client("s3")
        BucketName = bucketName
        with open(fileName) as f:
           object_data = f.read()
           s3.put_object(Body=object_data, Bucket=BucketName, Key=keyName)
    

    【讨论】:

    • 您的示例在导入后看起来会更干净。我还认为,如果您使用 BytesIO 作为缓冲区添加第二个示例,您将获得更多积分。
    • import pyarrow as pa , import pyarrow.parquet as pq 是必需的。
    • 分区拼花怎么写?
    【解决方案2】:

    供您参考,我有以下代码作品。

    s3_url = 's3://bucket/folder/bucket.parquet.gzip'
    df.to_parquet(s3_url, compression='gzip')
    

    要使用to_parquet,您需要安装pyarrowfastparquet。此外,请确保您的 configcredentials 文件中包含正确的信息,这些文件位于 .aws 文件夹中。

    编辑:此外,还需要s3fs。见https://stackoverflow.com/a/54006942/1862909

    【讨论】:

    • 我的 .aws/config 和凭证文件中有多个配置文件...有没有办法设置要使用的配置文件? (我想设置我的 ENV var: AWS_PROFILE= 会起作用,但在代码中会很好)
    • 是的,您首先导入boto3,然后使用session = boto3.Session(profile_name={your_profile}") 设置您的个人资料
    • 为了完整起见,如果您想要 .parquet 作为输出文件,请删除压缩参数并将文件名更改为 .parquet: s3_url = 's3://bucket/folder/bucket.parquet' df.to_parquet(s3_url)
    • 完全同意以 parquet 结尾的文件名,因为 .gzip 意味着您需要解压缩它。我的评论是警告使用 to_parquet(...) 的警告。如果您使用 engine=fast_parquet 并提供 partition_cols,to_parquet 会在您的工作目录中留下以“s3:”开头的目录路径。请注意。
    【解决方案3】:

    下面的函数在缓冲区中获取 parquet 输出,然后将 buffer.values() 写入 S3,无需在本地保存 parquet

    此外,由于您正在创建一个 s3 客户端,因此您可以使用 aws s3 密钥创建凭据,这些密钥可以存储在本地、气流连接或 aws 机密管理器中

    def dataframe_to_s3(s3_client, input_datafame, bucket_name, filepath, format):
    
            if format == 'parquet':
                out_buffer = BytesIO()
                input_datafame.to_parquet(out_buffer, index=False)
    
            elif format == 'csv':
                out_buffer = StringIO()
                input_datafame.to_parquet(out_buffer, index=False)
    
            s3_client.put_object(Bucket=bucket_name, Key=filepath, Body=out_buffer.getvalue())
    

    S3_client 只不过是一个 boto3 客户端对象。希望这会有所帮助!

    礼貌-https://stackoverflow.com/a/40615630/12036254

    【讨论】:

    【解决方案4】:

    对于 python 3.6+,AWS 有一个名为 aws-data-wrangler 的库,它有助于 Pandas/S3/Parquet 之间的集成

    安装做;

    pip install awswrangler
    

    如果您想将您的 pandas 数据框作为 parquet 文件写入 S3,请执行;

    import awswrangler as wr
    wr.s3.to_parquet(
        dataframe=df,
        path="s3://my-bucket/key/my-file.parquet"
    )
    

    【讨论】:

    • 警告:与pandas.DataFrame.to_parquet() 不同,wrangler 无法将 kwargs 传递给底层 parquet 库。这意味着如果需要,您不能设置较低级别的选项。当 PyArrow 无法推断表架构时,我遇到了这个问题——在 pandas 中,您可以通过 explicitly defining a PyArrow 架构解决这个问题
    猜你喜欢
    • 2020-03-23
    • 2018-11-10
    • 1970-01-01
    • 2018-06-24
    • 2018-12-22
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 2021-03-26
    相关资源
    最近更新 更多