以块的形式读入非常大的csv,并附加到一个 Dataframe 以用于计算

nom7f22z  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(125)

我有一个8 GB的大csv文件。我的RAM大小是16 GB。当我试图读入它时:
我得到一个内存错误。所以我试着用chunksize参数读入它,像这样:

import pandas as pd
import csv

dtypes= {     "Column1": str, "Column2": str
        }

complete_data=pd.read_csv(r'C:\folder\test.csv', sep=";", encoding="utf-8", dtype=dtypes, decimal=",", chunksize=1000000)
dfcompl = pd.concat(complete_data, ignore_index=True)

再次,我得到一个内存错误。根据this解决方案,我尝试:

import pandas as pd
import csv

dtypes= {     "Column1": str, "Column2": str
        }

with pd.read_csv(r'C:\folder\test.csv', sep=";", encoding="utf-8", dtype=dtypes, decimal=",", chunksize=1000000) as reader:
    for chunk in reader:
        process(chunk)
        
dfcompl = pd.concat(chunk)

但是我得到了一个错误NameError: name 'process' is not defined。显然我必须改变“进程”。但是,我不知道该怎么做。看起来实际上是一个简单的任务,我希望简单地添加块大小将解决它,但是我不知道如何解决这个问题。
那么,我怎样才能读入一个大的csv文件,并附加到一个 Dataframe ,我可以与Pandas工作?
我不想用dask。
我的问题还在于,即使我逐块处理并导出(例如)到pkl文件,最后我仍然会遇到问题,即如果我试图连接这些pkl文件,我会再次收到内存错误。

yqkkidmi

yqkkidmi1#

如果你想在一个 Dataframe 中收集所有的数据块,那么分块阅读csv文件就没有真实的了--它需要大约8 GB的内存无论如何。分块背后的整个想法是分块处理你的数据,所以你永远不需要完整的内存(如果你的CSV不是8 GB,而是80 GB!)。这正是你的第二个代码片段所需要的:

import pandas as pd
import csv

dtypes= {     "Column1": str, "Column2": str
        }

with pd.read_csv(r'C:\folder\test.csv', sep=";", encoding="utf-8", dtype=dtypes, decimal=",", chunksize=1000000) as reader:
    for chunk in reader:
        process(chunk)
        
dfcompl = pd.concat(chunk)

其中 process 是一个函数,它对你的数据进行计算。**你必须实现它。你得到一个数据块,处理它,然后立即丢弃它。
试着从这个Angular 看待你的任务,你真的需要所有的数据一次或者你可以做一些增量,逐行,如果把它放在一些极端?
更新
因此,如果只想收集Column 3〈900的行,可以执行以下操作:

output = None

with pd.read_csv(r'C:\folder\test.csv', sep=";", encoding="utf-8", dtype=dtypes, decimal=",", chunksize=1000000) as reader:
    for chunk in reader:
        filtered = chunk['Column3'] < 900

        if output is None:
            output = filtered
            continue

        output = pd.concat([filtered, output])
        
output.to_csv(some_output_path)

这不是最佳的,有点难看,但说明了这个想法。

0kjbasz6

0kjbasz62#

我觉得原帖可能指的是自己的职能"流程"
试试这个

import pandas as pd

dtypes= {     "Column1": str, "Column2": str
        }

dfcompl=None
with pd.read_csv(r'C:\folder\test.csv'
  , sep=";", encoding="utf-8"
  , dtype=dtypes
  , decimal=","
  , chunksize=1000000) as reader:
    for chunk in reader:
        if dfcompl is None:
            dfcompl=chunk
        else:
            dfcompl=pd.concat([dfcompl,chunk], axis=0)
        
dfcompl

dfcompl是您需要的最后一个 Dataframe ,我用None初始化它,然后对每个块使用pd.concat([ dfcompl, chunk ], axis=0)作为前一个 Dataframe 。注意,到目前为止,axis = 0是在末尾进行concat或append的方式。
希望这能有所帮助。

相关问题