使用 pyarrow 如何附加到镶木地板文件?

Posted

技术标签:

【中文标题】使用 pyarrow 如何附加到镶木地板文件?【英文标题】:Using pyarrow how do you append to parquet file? 【发布时间】:2018-04-17 06:00:54 【问题描述】:

如何使用pyarrow 附加/更新到parquet 文件?

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq


 table2 = pd.DataFrame('one': [-1, np.nan, 2.5], 'two': ['foo', 'bar', 'baz'], 'three': [True, False, True])
 table3 = pd.DataFrame('six': [-1, np.nan, 2.5], 'nine': ['foo', 'bar', 'baz'], 'ten': [True, False, True])


pq.write_table(table2, './dataNew/pqTest2.parquet')
#append pqTest2 here?  

我在文档中没有找到关于附加镶木地板文件的内容。而且,您能否使用pyarrow 和多处理来插入/更新数据。

【问题讨论】:

您是否故意在两个表中放置了完全不同的列名? 【参考方案1】:

我遇到了同样的问题,我想我可以使用以下方法解决它:

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq


chunksize=10000 # this is the number of lines

pqwriter = None
for i, df in enumerate(pd.read_csv('sample.csv', chunksize=chunksize)):
    table = pa.Table.from_pandas(df)
    # for the first chunk of records
    if i == 0:
        # create a parquet write object giving it an output file
        pqwriter = pq.ParquetWriter('sample.parquet', table.schema)            
    pqwriter.write_table(table)

# close the parquet writer
if pqwriter:
    pqwriter.close()

【讨论】:

当然,这取决于数据,但以我的经验chunksize=10000 太大了。在大多数情况下,大约 100 的块大小值对我来说工作得更快 if 后面的 else 是不必要的,因为在这两种情况下你都在写表。 谢谢!到目前为止,用于增量写入 parquets 的 api 确实没有很好的文档记录。 @YuryKirienko 我用chunksize=1e5 获得了最好的性能。对人们的最佳建议是:以不同的价值观为基准,看看什么最适合你。 此解决方案仅在编写器仍处于打开状态时才有效...更好的方法是将文件放入目录中。 pandas/pyarrow 将在读取目录时将两个文件都附加到数据帧中。【参考方案2】:

在您的情况下,列名不一致,我使三个示例数据框的列名一致,以下代码对我有用。

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq


def append_to_parquet_table(dataframe, filepath=None, writer=None):
    """Method writes/append dataframes in parquet format.

    This method is used to write pandas DataFrame as pyarrow Table in parquet format. If the methods is invoked
    with writer, it appends dataframe to the already written pyarrow table.

    :param dataframe: pd.DataFrame to be written in parquet format.
    :param filepath: target file location for parquet file.
    :param writer: ParquetWriter object to write pyarrow tables in parquet format.
    :return: ParquetWriter object. This can be passed in the subsequenct method calls to append DataFrame
        in the pyarrow Table
    """
    table = pa.Table.from_pandas(dataframe)
    if writer is None:
        writer = pq.ParquetWriter(filepath, table.schema)
    writer.write_table(table=table)
    return writer


if __name__ == '__main__':

    table1 = pd.DataFrame('one': [-1, np.nan, 2.5], 'two': ['foo', 'bar', 'baz'], 'three': [True, False, True])
    table2 = pd.DataFrame('one': [-1, np.nan, 2.5], 'two': ['foo', 'bar', 'baz'], 'three': [True, False, True])
    table3 = pd.DataFrame('one': [-1, np.nan, 2.5], 'two': ['foo', 'bar', 'baz'], 'three': [True, False, True])
    writer = None
    filepath = '/tmp/verify_pyarrow_append.parquet'
    table_list = [table1, table2, table3]

    for table in table_list:
        writer = append_to_parquet_table(table, filepath, writer)

    if writer:
        writer.close()

    df = pd.read_parquet(filepath)
    print(df)

输出:

   one  three  two
0 -1.0   True  foo
1  NaN  False  bar
2  2.5   True  baz
0 -1.0   True  foo
1  NaN  False  bar
2  2.5   True  baz
0 -1.0   True  foo
1  NaN  False  bar
2  2.5   True  baz

【讨论】:

【参考方案3】:

一般来说,Parquet 数据集由多个文件组成,因此您可以通过将附加文件写入数据所属的同一目录来追加。能够轻松连接多个文件会很有用。我打开了https://issues.apache.org/jira/browse/PARQUET-1154,以便在 C++(以及 Python)中轻松实现这一点

【讨论】:

请包括更新数据。也许箭头中的某些东西可能会起作用。 请向 Arrow 和 Parquet 的邮件列表提出您的问题。 Stack Overflow 不是获得支持的最佳场所 parquet-tools 命令parquet-merge 不是一个选项吗? - 至少从命令行? (免责声明我还没有尝试过) parquet 文件有时在 Windows 上显示为单个文件。如何在 Windows 上将其视为文件夹?

以上是关于使用 pyarrow 如何附加到镶木地板文件?的主要内容,如果未能解决你的问题,请参考以下文章

覆盖和附加到镶木地板有啥区别

无法将数据附加到镶木地板 [FileAlreadyExists 异常]

如何使用 pyarrow 和 parquet 保存具有自定义类型的 pandas DataFrame

如何使用 Pyarrow 更改镶木地板文件中列的名称?

如何使用 pyarrow 从 S3 读取镶木地板文件列表作为熊猫数据框?

如何在 python 中使用 pyarrow 从 S3 读取分区镶木地板文件