以Python中高效使用内存的方式从流数据创建 Parquet 文件

9
似乎在Python中创建Parquet文件的最常见方法是首先创建一个Pandas数据框架,然后使用pyarrow将表格写入parquet。我担心这可能会在内存使用方面过度负担,因为它需要至少在内存中存储一个完整的数据集以便创建Pandas数据框架。
我想知道是否由于列压缩要求而需要将整个数据集加载到内存中,或者是否存在更有效和基于流的方法。在我的情况下,我将以流方式接收记录。对于类似的CSV输出过程,我们按1000行一批将行写入磁盘,因此需要保存在内存中的行数从未达到完整数据集的大小。
我应该…?:
1.只需创建一个Pandas数据框架,然后将其写入parquet。(意味着整个数据集都需要存储在内存中,但我们将其视为必要的要求。) 2.在接收到每1000行左右的记录时,使用某种适合流式处理的方式写入,以最小化整个过程中的总点时RAM消耗。(我没有看到有关如何执行此操作的文档,并且我不确定它是否适用于parquet。) 3.将所有内容写入CSV,然后使用一个智能读取/分析CSV内容并在事后创建压缩的parquet的函数。(运行时间可能会变慢,但内存占用低,大型文件故障几率低。)
想法?建议?

写入多个行组是有效的 - https://dev59.com/FVUL5IYBdhLWcg3wQWOD#74258957 - ns15
2个回答

3
使用一些适合流式传输的方法,每次接收大约1000行数据并写入,以最小化整个过程中的实时内存消耗。您可以这样做。
(我没有看到有关如何进行此操作的任何文档,也不确定对于parquet是否是选项。)
至少现在https://arrow.apache.org/docs/python/generated/pyarrow.parquet.ParquetWriter.html有一些关于如何进行此操作的文档 - 具体来说是write_batch函数。
这是一个例子,但根据数据源可能需要进行一些微调。例如,如果已经“分块”或者模式必须从数据中推断出来而不是像这里一样硬编码。
该示例主要通过Pandas完成,因为这是将行转换为列以创建每个RecordBatch的便捷方式,但是有其他创建每个RecordBatch的方法不需要使用pandas
import itertools
import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq

# Any iterable that yields rows as tuples
def get_rows():
    for i in range(0, 10000):
        yield (1, 2)

# Chunk the rows into arrow batches
def get_batches(rows_iterable, chunk_size, schema):
    rows_it = iter(rows_iterable)
    while True:
        batch = pa.RecordBatch.from_pandas(
            pd.DataFrame(itertools.islice(rows_it, chunk_size), columns=schema.names),
            schema=schema, preserve_index=False,
        )
        if not batch:
            break
        yield batch

# Could be inferred from data, but note that the schema has to be
# known when creating the ParquetWriter object
schema = pa.schema([
    ('a', pa.int32()),
    ('b', pa.int32()),
])
rows = get_rows()
batches = get_batches(rows, chunk_size=1000, schema=schema)

# Write the batches
with pq.ParquetWriter('example.parquet', schema=schema) as writer:
    for batch in batches:
        writer.write_batch(batch)

1
您希望在Parquet中使用行组。请见此处了解其含义,简要版是列式数据仅限于一定数量的行块,并且每个块都可以单独追加到文件中。您可以使用PyArrow将此功能实现为一个流入数据流。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接