如何加快第一列分割文件的代码速度

时间:2016-04-03 02:43:49

标签: python pandas

import numpy  
import pandas as pd  
import math as m
import os
import datetime
from time import gmtime, strftime


final = "D:/Technical_Data/final.csv"

group_col_indx = 0
group_col = pd.read_csv(final, usecols=[group_col_indx])
keys = group_col.iloc[:,0].unique()

for key in keys:
    df_list = []
    print key
    reader = pd.read_csv(final, chunksize=20000)
    for chunk in reader:
        good_rows = chunk[chunk.iloc[:,group_col_indx] == key]
        df_list.append(good_rows)
    df_key = pd.concat(df_list)
    file_save = "D:/Technical_Data_by_Date/" + str(key) + ".csv"
    df_key.to_csv(file_save, header=False,index=False)

借助堆栈溢出和google,我想出了使用第1列将大文件拆分成多个文件的代码。 我在我的机器上运行它,它有8 GB的RAM。该程序运行速度非常慢。我怎样才能加快速度?我做了过去2天的研究,这是我提出的脚本

2 个答案:

答案 0 :(得分:2)

虽然我喜欢大熊猫,但在这种情况下我不会使用它,因为您似乎不想处理您的数据,只需将其拆分。因此,如果您只想按键(日期)拆分CSV文件,只需使用gawk即可:

假设您的密钥位于第二列$2(如果您的密钥列位于第一列中,请更改$2 - > $1)...

prg.awk

{
    key = $2
    print > "D:/Technical_Data_by_Date/"key".csv"
}

命令:

gawk -F"," -f prg.awk final.csv

它可以更多更快

如果您想使用python + pandas - 请务必阅读输入的CSV文件 (目前您执行number of keys + 1次,即大约601次):

import pandas as pd

fn = 'D:/Technical_Data/final.csv'
sep=','
out_path = 'D:/Technical_Data_by_Date'
chunk_size = 20000
key_col_idx = 0

reader = pd.read_csv(fn, sep=sep, chunksize=chunk_size)

for chunk in reader:
    # loop through keys
    for key in chunk.iloc[:, key_col_idx].unique():
        # writing (appending: mode='a') data to CSV files (by key)
        chunk[chunk.iloc[:, key_col_idx] == key] \
             .to_csv('{0}/{1}.csv'.format(out_path, key),
                     mode='a', header=None, index=False)

PS的诀窍是在调用mode='a'方法时使用.to_csv()参数,这会将数据附加到CSV文件而不是覆盖它

PPS与AWK解决方案相比会更慢

答案 1 :(得分:0)

我不知道这是否会更快,但由于您有太多输出文件要立即打开,您可以分组打开文件。这将减少扫描输入文件所需的次数。在这里,我只是逐行读取并执行多个倒带​​ - 读写循环。如果您的csv很简单,可以加快速度,允许第一个逗号上的简单split找到密钥而不是使用庞大的csv模块。

如果不是更快......至少有一个数据点告诉你pandas游戏是否值得。

import os
import csv

final = "D:/Technical_Data/final.csv"
outdir = "D:/Technical_Data_by_Date"
maxfiles = 128

with open(final) as infile:
    reader = csv.reader(infile, buffering=32*1024*1024)

    # scan file for keys
    keys = list(set(row[0] for row in reader))

    # scan and write 'maxfiles' at a time
    for keyidx in range(0, len(keys), maxfiles):
        keygrp = keys[keyidx:keyidx+maxfiles]
        outcsvs = {}
        outfps = []
        try:
            # open next group of output files
            for key in keygrp:
                fp = open(os.path.join(outdir, "{}.csv".format(key)), 
                    "w", newline='', buffering=1024*1024)
                outcsvs[key] = csv.writer(fp)
                outfps.append(fp)            
            # rewind input and extract rows
            infile.seek(0)
            for row in reader:
                writer = outcsvs.get(row[0])
                if writer:
                    writer.writerow(row)
        finally:
            for fp in outfps:
                fp.close()