熊猫的记忆问题(了解记忆问题)

时间:2018-07-09 10:29:14

标签: python database pandas memory deep-learning

问题是我有299个.csv文件(每个文件150-200 MB,平均数百万行和12列-构成一年的数据(约52 GB /年),我有6年了,我想将它们全部串联起来),我想用python将它们串联成一个.csv文件。如您所料,尝试以下代码时遇到内存错误(我的机器具有16GB的RAM):

import os, gzip, pandas as pd, time

rootdir = "/home/eriz/Desktop/2012_try/01"

dataframe_total_list = []

counter = 0 

start = time.time()

for subdir, dirs, files in os.walk(rootdir):
    dirs.sort()

for files_gz in files:

    with gzip.open(os.path.join(subdir, files_gz)) as f:

         df = pd.read_csv(f)
         dataframe_total_list.append(df)
         counter += 1
         print(counter)

total_result = pd.concat(dataframe_total_list)
total_result.to_csv("/home/eriz/Desktop/2012_try/01/01.csv", encoding="utf-8", index=False)

我的目标:获取单个.csv文件,然后将其用于训练DL模型等。

我的约束:我对海量数据非常陌生,但是我完成了部分工作:

  1. 我知道多处理对我的开发没有太大帮助;这是一项顺序工作,我需要完成每个任务,以便我可以开始下一个任务。主要问题是内存用完了。

  2. 我知道,即使添加了块大小,熊猫也可以很好地工作。但是,由于数据量巨大,因此内存问题仍然存在。

  3. 我试图将工作分解为一些小任务,以免耗尽内存,但是无论如何我以后会在连接时使用它。

我的问题:

  1. 是否仍然可以使用我不知道的其他方式使用python / pandas来执行此任务,或者无论使用哪种数据库方法,都需要切换?你能建议哪个吗?

  2. 如果数据库方法是唯一的途径,那么当需要执行基于python的操作来训练DL模型时,我会遇到问题吗?我的意思是,如果我需要使用pandas / numpy函数来转换数据,是否可能或者由于文件大小而出现问题?

非常感谢,对于这个主题的深入解释,我将不胜感激。

更新10/7/2018

尝试并使用@mdurant指出的以下代码段后,我学到了很多东西,并更正了对dask和内存问题的看法。

课程:

  • Dask将在执行第一个预处理任务后使用(如果最终您最终会得到大文件,而熊猫很难加载/处理它们)。获得“所需”的庞然大物文件后,可以将其加载到dask.dataframe对象中,而不会出现任何问题并进行处理。

  • 与内存有关: 第一课-提出一个过程,这样您就不必合并所有文件,并且用完了内存;只需通过更改dtype,删除列,重采样来处理它们的循环并减少其内容... 第二课-尝试仅将所需的内容存储到内存中,以免耗尽内存。第三课-如果其他任何课程都不适用,只需寻找EC2实例,大数据工具(如Spark,SQL等)。

感谢@mdurant和@ gyx-hh的时间和指导。

1 个答案:

答案 0 :(得分:1)

第一件事:将每个CSV的内容并接成一个巨大的CSV很简单,您不需要熊猫或其他任何东西(甚至是python)

outfile = open('outpath.csv', 'w')
for files_gz in files:
    with gzip.open(os.path.join(subdir, files_gz)) as f:
        for line in f:
            outfile.write(line)
outfile.close()

(如果每个CSV的标题都带有列名,则您可能要忽略它们的第一行)。

对数据进行处理比较困难。原因是,尽管Dask可以读取所有文件并将其作为单个数据帧处理在集合上,但是如果 any 文件导致的内存超出系统的处理能力,则处理将失败。这是因为随机访问不会与gzip压缩混合使用。

但是,(大概)输出文件未压缩,因此您可以执行以下操作:

import dask.dataframe as dd
df = dd.read_csv('outpath.csv')  # automatically chunks input
df[filter].groupby(fields).mean().compute()

在这里,只有对dd.compute()的引用是针对dask的。