将巨大的dask数据帧写入镶木地板时内存不足

时间:2019-03-04 07:44:27

标签: python parquet dask

我基本上是将一些csv文件转换为parquet。为此,我决定使用dask,在csv上读取dask并将其写回到parquet。我正在按照客户要求使用大块大小(500 MB)。 csv的大小为15 GB和更大(直到50 GB),机器具有64 GB的RAM。每当我运行基本的to_parquet命令时,RAM就会开始增加,并且最终变得如此之高,以至于Linux 杀死。有人知道为什么会这样吗?当我不指定块大小时,它可以工作,但会创建很多小木地板文件(24 MB)。有没有办法解决此问题,请创建至少500 MB的

块。
_path = 'E://'

dt = dd.read_csv(_path+'//temporal.csv', blocksize = 500e5)

dt.to_parquet(path=_path+'/t.parq', compression='gzip')`

2 个答案:

答案 0 :(得分:0)

请让我们将其作为详尽的评论。为什么不先将文件拆分为500 Mb的csv,然后用dask转换为镶木地板?

import pandas as pd
import numpy as np
import os

fldr = "data/splitted"
fldr_out = "data/splitted_parquet"
os.makedirs(fldr)
os.makedirs(fldr_out)

# this for a ~4gb csv
rows = int(1e7)
cols = 20
df = pd.DataFrame(np.random.rand(rows, cols),
                  columns=["col_{}".format(i) for i in range(cols)])


df.to_csv("data/file.csv")

在Linux中,您可以将其拆分为500M的文件,

split -b 500M --additional-suffix=".csv" file.csv splitted/file_part_

现在您可以使用dask转换为实木复合地板

from dask import compute()
from dask import delayed

@delayed
def csv2parq(fn):
    out = fn.replace(fldr, fldr_out)
    pd.read_csv(fn).to_parquet(out)

fns = os.listdir(fldr)
fns = [os.path.join(fldr, fn) for fn in fns]
compute([csv2parq(fn) for fn in fns])

答案 1 :(得分:0)

您说您的分区最终每个大约15GB。如果您将Dask与许多线程一起使用,则一次可能在内存中有多个线程。如果只有64GB,那么很可能用完了ram。

一些选项:

  1. 使用较小的块大小
  2. 对数据进行不同的编码,以节省空间。例如,文本数据(Python中内存膨胀的常见原因)可能会更有效地存储为类别
  3. 使用更少的线程