【问题标题】:Loading Dataframe from Parquet and calculating max explodes in RAM从 Parquet 加载 Dataframe 并计算 RAM 中的最大值
【发布时间】:2021-06-18 15:12:46
【问题描述】:

我是 Dask 的新手,我使用行组将 pandas Dataframe 导出到 Parquet:

x.to_parquet(path + 'ohlcv_TRX-PERP_978627_rowgrouped.prq', row_group_size=1000)

然后我尝试用 Dask 加载它,它似乎可以正常工作(?):

x = dd.read_parquet(path + 'ohlcv_TRX-PERP_978627_rowgrouped.prq')
x

# Note: The dataframe has almost 2000 columns, I clipped them for here
Dask DataFrame Structure:
                        open     h
npartitions=978                   
2019-07-21 23:55:00  float64  floa
2019-07-22 16:35:00      ...      
                      ...      ...
2021-05-30 17:06:00      ...      
2021-05-31 03:32:00      ...      
Dask Name: read-parquet, 978 tasks

到目前为止,没有问题。但是当我在上面调用x.max().compute() 时,Dask 似乎将整个数据集加载到 RAM 中(至少 RAM 像疯了一样增加)然后崩溃。只看max()

x = x.max()
x

Dask Series Structure:
npartitions=1
ACCBL_10    float64
volume          ...
dtype: float64
Dask Name: dataframe-max-agg, 1957 tasks

根据 Dask 教程 https://tutorial.dask.org/04_dataframe.html#Computations-with-dask.dataframe,据我了解,这应该可以正常工作(?)

当我尝试仅在一列上调用 max() 时,它也会内存不足:

x.open.max().compute()

我做错了什么,还是它应该如何工作,我必须做一些不同的事情?

我现在也尝试使用distributed 系统并将客户端限制为 10GB,但 Dask 再次占用了 24GB 的 RAM,并且只是打印了一个警告,表明工作组完全超出了设置的内存限制:

if __name__ == '__main__':

    client = Client(processes=False, memory_limit='5GB')

    x = dd.read_parquet(path + 'ohlcv_TRX-PERP_978627_rowgrouped.prq')
    print(x)
    s = x.max().compute()
    print(s)


distributed.worker - WARNING - Memory use is high but worker has no data to store to disk.  Perhaps some other process is leaking memory?  Process memory: 24.13 GB -- Worker memory limit: 5.00 GB

【问题讨论】:

  • 您知道您使用的是 fastparquet 还是 pyarrow 作为 parquet 引擎?您可能想尝试另一个。要获得最多一列,将columns= 提供给read_parquet 将确保您不会加载不必要的数据。你有几个核心?尝试使用比核心更少的工人运行。

标签: python pandas dask dask-dataframe vaex


【解决方案1】:

如果可能,我会将镶木地板保存到多个文件中(大小取决于您的硬件,但在笔记本电脑上每个分区大约 100-200 MB 比较好)。如果这不是一个选项,请尝试以下操作:

x.open.max(split_every=2).compute()

这样做的目的是让dask 计算每个分区的最大值,然后比较每 2 个分区的最大值,这样可以减少内存占用,但需要运行更多任务。您可以使用split_every 数字来查看您的硬件是否可以容忍更高的值,但希望 2 可以工作。

另外,如果您打算使用单个文件,使用vaex 可能会获得更好的性能,请参阅this comparison

【讨论】:

  • 谢谢,我试过了,但行为似乎相似 - Dask 只是占用 20GB 的 RAM。请注意,我可以在 Pandas 中加载 Dataframe 并进行计算 - 它会超过 RAM 并且几乎不会交换,但它会完成计算。所以我更加困惑 Dask 发生了什么。 ://
  • 不确定,我只使用了row_group_size,没有dask...如果你可以加载到pandas,那么你也可以用dd.from_pandas创建dask数据框,然后用ddf.to_parquet()持久化它.
猜你喜欢
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2013-05-13
  • 1970-01-01
  • 2014-10-10
  • 2018-10-12
  • 1970-01-01
相关资源
最近更新 更多