如何在 python 的 S3 中从 Pandas 数据帧写入镶木地板文件

Posted

技术标签:

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

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

【问题讨论】:

【参考方案1】:

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

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

这是一个简单的脚本,使用 pyarrow 和 boto3 创建临时拼花文件,然后发送到 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://***.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://***.com/a/40615630/12036254

【讨论】:

对于任何想知道什么是 input_dataframe.to_parquet 的人:***.com/questions/41066582/… 对于有时间戳的数据:***.com/questions/53893554/… 我按照这个并在文件中写入了垃圾值。 :( 可能出了什么问题?【参考方案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 架构解决这个问题

以上是关于如何在 python 的 S3 中从 Pandas 数据帧写入镶木地板文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Pandas Python 中从 Excel 导入 [重复]

在 python pandas 中从相同 csv(我自己的 json 格式)中的值创建一个 Json 列

在 aws lambda 中在 python 中从 ANSI 转换为 UTF-8

如何在 pandas 数据框中从 groupby 的结果生成所有值对

如何在streamlit中从用户读取csv文件并转换为pandas数据框

在 Python Pandas 中使用 read_parquet 从 AWS S3 读取镶木地板文件时出现分段错误