读取大熊猫中的多个CSV文件

时间:2019-03-04 16:38:39

标签: python pandas jupyter-notebook sklearn-pandas

当我们有多个csv文件且所有csv的总大小约为20gb时,如何分块导入和读取多个CSV?

我不想使用Spark,因为我想在SkLearn中使用模型,所以我想要Pandas本身的解决方案。

我的代码是:

allFiles = glob.glob(os.path.join(path, "*.csv"))
df = pd.concat((pd.read_csv(f,sep=",") for f in allFiles))
df.reset_index(drop=True, inplace=True)

但是这失败了,因为我的路径中所有csv的总大小为17gb。

我想分块阅读它,但是如果尝试这样会出现一些错误:

  allFiles = glob.glob(os.path.join(path, "*.csv"))
  df = pd.concat((pd.read_csv(f,sep=",",chunksize=10000) for f in allFiles))
  df.reset_index(drop=True, inplace=True)

我得到的错误是:

  

“无法连接类型为“”的对象;只有pd.Series,pd.DataFrame和pd.Panel(已弃用)objs有效”

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:0)

要读取较大的csv文件,可以使用chunksize,但在这种情况下,您必须像这样使用迭代器:

for df in pd.read_csv('file.csv', sep=',', iterator=True, chunksize=10000):
    process(df)

您必须合并或附加每个块

或者您可以这样做:

df = pd.read_csv('file.csv',, sep=',', iterator=True, chunksize=10000)
for chunk in df:
    process(chunk)

读取多个文件:例如

listfile = ['file1,'file2]
dfx = pd.DataFrame()
def process(d):
    #dfx=dfx.append(d) or dfx = pd.concat(dfx, d)
    #other coding

for f in listfile:
    for df in pd.read_csv(f, sep=',', iterator=True, chunksize=10000):
        process(df)

拥有大量文件后,您可以使用多处理库中的DASK或Pool启动大量读取过程

无论如何,要么您有足够的内存,要么浪费时间

答案 1 :(得分:0)

这是一个有趣的问题。我没有尝试过,但是我认为代码看起来像下面的脚本。

import pandas as pd
import csv
import glob
import os

#os.chdir("C:\\your_path\\")
results = pd.DataFrame([])
filelist = glob.glob("C:\\your_path\\*.csv")
#dfList=[]
for filename in filelist:
    print(filename)  
    namedf = pd.read_csv(filename, skiprows=0, index_col=0)
    results = results.append(namedf)

results.to_csv('C:\\your_path\\Combinefile.csv')


chunksize = 10 ** 6
for chunk in pd.read_csv('C:\\your_path\\Combinefile.csv', chunksize=chunksize):
    process(chunk)

也许您可以将所有内容加载到内存中并直接对其进行处理,但是处理所有内容可能会花费更长的时间。

答案 2 :(得分:0)

执行此操作的一种方法是使用pd.read_csv(file,chunksize = chunksize)对数据帧进行分块,然后,如果您读取的最后一个块短于块大小,请保存多余的位,然后将其添加到第一个下一块的文件。

但是请确保读取下一个文件的较小的第一块,使其等于总块大小。

def chunk_from_files(dir, master_chunksize):
    '''
    Provided a directory, loops through files and chunks out dataframes.
    :param dir: Directory to csv files.
    :param master_chunksize: Size of chunk to output.
    :return: Dataframes with master_chunksize chunk.
    '''
    files = os.listdir(dir)

    chunksize = master_chunksize
    extra_chunk = None # Initialize the extra chunk.
    for file in files:
        csv_file = os.path.join(dir, file)

        # Alter chunksize if extra chunk is not None.
        if extra_chunk is not None:
            chunksize = master_chunksize - extra_chunk.shape[0]

        for chunk in pd.read_csv(csv_file, chunksize=chunksize):
            if extra_chunk is not None: 
                # Concatenate last small chunk of previous file with altered first chunk of next file.
                chunk = pd.concat([chunk, extra_chunk])
                extra_chunk = None
                chunksize = master_chunksize # Reset chunksize.
            elif chunk.shape[0] < chunksize:
                # If last chunk is less than chunk size, set is as the extra bit.
                extra_chunk = chunk
                break

            yield chunk
相关问题