Python Pandas-加快CSV加入

时间:2019-02-15 07:25:48

标签: python pandas optimization

我有一个优化问题。我需要在一个唯一的csv中加入一些csv(都具有相同的结构)。

我的文件夹的结构遵循时间顺序:年/月/日/小时_file_identifier.csv。因此16y * 365d * 24h = 140160个文件。这是我可以拥有的最大文件数。按天编制索引的每个文件夹可以具有任意数量的文件(我也是使用python脚本生成的)。由于每N次迭代文件的数量将超过ext4文件系统所允许的最大值,因此我需要将所有文件加入hour_indexed文件中,以免遇到此问题。

因此,我称为join_routine的输入是按时间索引的文件夹,例如:

2001/9/3/
2002/8/4/

每个文件夹可以包含以下数量的文件:

2001/9/3/
    1-01.csv
    1-02.csv
    2-01.csv
2002/8/4/
    1-01.csv
    2-01.csv
    3-01.csv
    3-01.csv

join_routine的结果应为:

2001/9/3/
    1-joined.csv
    2-joined.csv
2002/8/4/
    1-joined.csv
    2-joined.csv
    3-joined.csv

为此,我开发了以下代码:

def join_routine():
#    print('JOIN ROUTINE')
    directory_list = [x.replace('\\','/') for x in glob.glob('data/csv/plays/*/*/*/')]

    for directory in directory_list:
        for hour in range(0,13):
            file_list = [x.replace('\\','/') for x in glob.glob(directory+ str(hour) +'-*.csv')]
            if len(file_list) > 0:
                df = read_csv_list(file_list)
                df.to_csv(directory+str(hour)+'-joined.csv', index = False)
                for file in [ x for x in file_list if x not in directory+str(hour)+'-joined.csv']:
                    os.remove(file)

def read_csv_list(file_list):
    df_list = []
#    with progressbar.ProgressBar(max_value=len(file_list)) as bar:
#        i = 0
    for file in file_list:
        df = pd.read_csv(file)
        df_list.append(df)
#            i = i + 1
#            bar.update(i)

    return pd.concat(df_list, axis = 0, ignore_index = True)

join_routine函数在单个过程中处理每个文件夹的联接。我想知道是否有更好,更重要,更快的方法。 join_routine占用了超过10倍的文件创建量(在具有16个工作程序的并行进程池中完成)。我需要做join_routine 21次,以这种速度要花1个多星期,这是不可行的。 有想法吗?

1 个答案:

答案 0 :(得分:2)

请不要使用熊猫!

实验1:读取文件并逐行追加到另一行 (来自how to merge 200 csv files in Python的代码):

import time

#%%
start1 = time.time()
fout=open("out.csv","a")
# first file:
for line in open("file.csv"):
    fout.write(line)
# now the rest:    
for num in range(2,201):
    f = open("file.csv")
    f.__next__() # skip the header
    for line in f:
         fout.write(line)
    f.close() # not really needed
fout.close()
end1 = time.time()
print(end1-start1) #0.3000311851501465

实验2(使用熊猫读取,合并和写入csv文件):

import time
import pandas as pd
start2 = time.time()
df_list = []
for i in range(200):
    df = pd.read_csv('file.csv')
    df_list.append(df)
df = pd.concat(df_list, axis = 0, ignore_index = True)
df.to_csv('out2.csv', index = False)
end2 = time.time()
print(end2-start2) #3.0119707584381104