首页 > 解决方案 > 让我的代码更快 - 将 CSV 加载到选定列上的 pandas 数据框中并合并它们

问题描述

我在以“1251”结尾的文件夹中有三个 CSV 文件。我想遍历文件夹,选择这些文件,将它们分块加载到 pandas 数据帧中,并将它们与选定的列合并。

90MB 的文件轻而易举,但脚本需要 15 分钟才能添加 700 MB 的文件(超过 3 百万行)。整个操作需要 20 分钟才能完成 - 这是不可接受的。

有什么办法可以改变和加快程序?我的意思是将 CSV 分块加载到 pandas 数据帧,然后将它们合并/附加/连接到一个文件中。

这适用于小文件,但对于大 csv 文件需要更快。我发现了很多有好主意的问题,但这应该可行 - 不知道为什么这么慢。任何想法如何使它更快?

import os
import sys
import struct
import fileinput
import csv
import pandas as pd



cwd = 'C:\\Users\\'
print(cwd)
directory = (cwd + '\\FINAL\\')
directory2 = (cwd + '\\FINAL\\CSV')
print(directory)
x=pd.DataFrame()
for file in os.listdir(directory):
    if file.endswith( "1251.csv"):
        fajl = os.path.splitext(file)[0]
        print(fajl)
        for chunk in pd.read_csv(directory + '\\' + fajl + ".csv", sep=",",error_bad_lines=False, encoding='latin-1',low_memory=False, chunksize=100000):

            mylist = []
            mylist.append(chunk)
            big_data = pd.concat(mylist, axis= 0)


            big_data = big_data.fillna(value='')
            selected = big_data[['SYS', 'MANDT', 'AGR_NAME', 'OBJECT', 'AUTH', 'FIELD', 'LOW', 'HIGH', 'DELETED']]

            x=x.append(selected)

            x.to_csv(directory2 + '\\' + fajl + '.csv', sep=',', index=False)

标签: python

解决方案


我认为您的代码有几个问题。

  1. 你为什么要分块阅读?pandas 不能处理读取你的 csv 文件吗?或者这是为了加快代码速度?
  2. 出于某种原因,您在第二个 for 循环中重新初始化列表,本质上,此代码除了附加数据框外没有做任何事情:

        for chunk in pd.read_csv(directory + '\\' + fajl + ".csv", sep=",",error_bad_lines=False, encoding='latin-1',low_memory=False, chunksize=100000):
    
            mylist = []
            mylist.append(chunk)
            big_data = pd.concat(mylist, axis= 0)
    
    
            big_data = big_data.fillna(value='')
            selected = big_data[['SYS', 'MANDT', 'AGR_NAME', 'OBJECT', 'AUTH', 'FIELD', 'LOW', 'HIGH', 'DELETED']]
    
            x=x.append(selected)
    
  3. 假设 pandas 可以处理您的 csv(从您的帖子中不清楚每个 csv 有多大),我将通过以下方式进行处理(使用 pd.concat 处理包含多个 DataFrame 的列表比追加更有效):

    import csv
    import pandas as pd    
    cwd = 'C:\\Users\\'
    print(cwd)
    directory = (cwd + '\\FINAL\\')
    directory2 = (cwd + '\\FINAL\\CSV')
    print(directory)
    my_list = []
    for file in os.listdir(directory):
        if file.endswith( "1251.csv"):
            fajl = os.path.splitext(file)[0]
            print(fajl)
            curr_df = pd.read_csv(directory + '\\' + fajl + ".csv", sep=",",error_bad_lines=False, encoding='latin-1', usecols=['SYS', 'MANDT', 'AGR_NAME', 'OBJECT', 'AUTH', 'FIELD', 'LOW', 'HIGH', 'DELETED'])
            curr_df = curr_df.fillna(value='')
            my_list.append(curr_df)
    x = pd.concat(my_list)
    x.to_csv(directory2 + '\\' + fajl + '.csv', sep=',', index=False)
    
  4. 假设您确实必须分块阅读:

    import os
    import sys
    import struct
    import fileinput
    import csv
    import pandas as pd
    
    
    
    cwd = 'C:\\Users\\'
    print(cwd)
    directory = (cwd + '\\FINAL\\')
    directory2 = (cwd + '\\FINAL\\CSV')
    print(directory)
    x = []
    for file in os.listdir(directory):
        if file.endswith( "1251.csv"):
            fajl = os.path.splitext(file)[0]
            print(fajl)
    
            for chunk in pd.read_csv(directory + '\\' + fajl + ".csv", sep=",",error_bad_lines=False, encoding='latin-1',low_memory=False, chunksize=100000):
    
                x.append(chunk['SYS', 'MANDT', 'AGR_NAME', 'OBJECT', 'AUTH', 'FIELD', 'LOW', 'HIGH', 'DELETED'])
    big_data = pd.concat(x, axis=0)
    big_data = big_data.fillna(value='')
    big_data.to_csv(directory2 + '\\' + fajl + '.csv', sep=',', index=False)
    

推荐阅读