【问题标题】:pyarrow.parquet.write_table: memory usagepyarrow.parquet.write_table:内存使用情况
【发布时间】:2021-01-25 12:54:32
【问题描述】:

我需要使用 Python 准备 .parquet 文件,所以这是我的代码:

import numpy as np
import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
import sys
import mysql.connector
import json

def write_table(databaseServer, databaseDatabase, databaseUser, databasePassword, sql, fileName):
    result = 0;
    frame = {};
    convert_to_double = {};

    try:
        database = mysql.connector.connect(host=databaseServer, database=databaseDatabase, user=databaseUser, password=databasePassword)

        try:
            cursor = database.cursor(buffered=False)

            cursor.execute(sql)

            for desc in cursor.description:
                name = desc[0]
                type = desc[1]

                frame[name] = [];

                if mysql.connector.FieldType.get_info(type) == 'NEWDECIMAL':
                    convert_to_double[name] = True;

            records = cursor.fetchall()

            for record in records:
                i = 0;

                for name in cursor.column_names:
                    if name in convert_to_double:
                        frame[name].append(float(record[i]))
                    else:
                        frame[name].append(record[i])

                    i += 1

                result += 1;
        finally:
            cursor.close()
    finally:
        database.close()

    
    if result == 0:
        return result;
    
    df = pd.DataFrame(frame)
    table = pa.Table.from_pandas(df)
    pq.write_table(table, fileName)

    return result

问题是我在服务器上没有太多内存,但在此代码中,我将整个 SQL 查询加载到存储在内存中的列中。此外,我无法对数据进行分区以加载更少的数据(它已经按月进行了分区,我为 Amazon Athena 准备了 .parquet 文件)。

我的问题是:

  • 以这种方式准备 .parquet 文件时是否可以减少内存使用?
  • 这是一种从数据库中逐列查询数据然后将所有这些列写入单个 .parquet 的方法吗?
  • 如果我先在磁盘上写入 CSV,然后告诉 pandas 将此 .csv 转换为 .parquet,是否有助于减少内存使用?

谢谢。

【问题讨论】:

  • 我做了一些研究,发现比先制作 CSV 然后将此 CSV 转换为 .parquet 可将这种情况下的内存使用量减少 60%。仍然想知道是否有任何其他方法可以减少 pandas 的内存使用量

标签: python pandas parquet pyarrow


【解决方案1】:

此刻你是:

  • 将数据加载到内存中(以向量形式)
  • 将数据转换为 df
  • 将数据存储在 parquet 中

此策略仅在所有数据都可以存储在内存中时才有效。

您可以改为使用 ParquetWriter 将较小批量的数据写入 parquet 文件

一一回答你的问题:

  • 您可以通过使用 numpy 数组而不是 python 数组来减少内存占用。它们在内存方面效率更高。此外,您不应该调用fetchall(),而是从游标流式传输记录。

  • 我认为没有办法按列编写镶木地板文件列。您可以通过编写较小的行组来解决规模问题。

  • CSV 数据表示比 parquet 或 pandas 效率低,我不确定它是否有用。

【讨论】:

  • 嗨。感谢您的回答,我做了这些修改:从mysql中逐一流式传输行而不是fetchall(这很有帮助)并使用ParquetWriter。这会减少内存,但是使用 ParquetWriter 我得到了更大尺寸的结果 parquet 文件(15-25% 取决于块大小)。
  • 我不希望它显着增加您的文件大小。获得良好性能的推荐块大小为 50mb。
猜你喜欢
  • 1970-01-01
  • 2015-02-03
  • 2012-05-30
  • 2021-02-26
  • 2010-10-24
  • 2015-06-14
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多