我有一个~50GB的csv文件,我必须
我选择使用Pandas,并且有一种通用的方法来迭代一个方便的块大小(超过五十万行)的块来生成一个DataFrame,并将块附加到每个输出CSV。所以像这样:
_chunk_size = 630100
column_mapping = {
'first_output_specification' : ['Scen', 'MS', 'Time', 'CCF2', 'ESW10'],
# ..... similar mappings for rest of output specifications
}
union_of_used_cols = ['Scen', 'MS', 'Time', 'CCF1', 'CCF2', 'VS', 'ESW 0.00397', 'ESW0.08',
'ESW0.25', 'ESW1', 'ESW 2', 'ESW3', 'ESW 5', 'ESW7', 'ESW 10', 'ESW12',
'ESW 15', 'ESW18', 'ESW 20', 'ESW22', 'ESW 25', 'ESW30', 'ESW 35',
'ESW40']
chnk_iter = pd.read_csv('my_big_csv.csv', header=0, index_col=False,
iterator=True, na_filter=False, usecols=union_of_used_cols)
cnt = 0
while cnt < 100:
chnk = chnk_iter.get_chunk(_chunk_size)
chnk.to_csv('first_output_specification', float_format='%.8f',
columns=column_mapping['first_output_specification'],
mode='a',
header=True,
index=False)
# ..... do the same thing for the rest of the output specifications
cnt += 1
我的问题是真的慢。每个块大约花一分钟生成附加到CSV文件,因此我看了将近2个小时才能完成任务。
我尝试通过仅在使用CSV时使用列子集的并集来设置一些优化,以及设置na_filter=False
,但它仍然不可接受。
我想知道是否有更快的方法在Python中对CSV文件进行这种轻量级处理,或者通过优化或修正我的方法,或者可能只是有一个更适合此类工作的工具然后熊猫...对我来说(一个没有经验的Pandas用户)这看起来像它和Pandas一样快,但我可能错了。
答案 0 :(得分:6)
我不认为您从熊猫的数据框中获得任何优势,因此只是增加了开销。相反,你可以使用python自己的CSV module,它易于使用并且在C中进行了很好的优化。
考虑将更大的块读入内存(一次可能是10MB),然后在前进到下一个块之前写出每个重新格式化的列子集。这样,输入文件只能被读取和解析一次。
您可以尝试的另一种方法是使用Unix cut命令预处理数据,以仅提取相关列(这样Python就不必创建对象并为未使用的数据分配内存列):cut -d, -f1,3,5 somedata.csv
最后,尝试在PyPy下运行代码,以便通过跟踪JIT来优化脚本的CPU绑定部分。
答案 1 :(得分:0)
我会尝试使用python csv模块和生成器。
我发现生成器比解析大型服务器日志等其他方法要快得多。
import csv
def reader(csv_filename):
with open(csv_filename, 'r') as f:
csvreader = csv.reader(f, delimiter=',', quotechar="'")
for line in csvreader:
yield line # line is a tuple
def formatter(lines):
for line in lines:
# format line according to specs
yield formatted_line
def write(lines, csv_filename):
with open(csv_filename, 'w') as f:
writer = csv.writer(f)
for line in lines:
writer.writerow(line)
lines = reader('myfile.in.csv')
formatted_lines = formatter(lines)
write(formatted_lines, 'myfile.out.csv')
这只是用于读取将单个输入csv转换为单个输出csv,但您可以编写formatter和writer来输出多个文件。
(我现在看到这个问题已经过了一个月 - 不确定你是否已经解决了问题 - 如果没有,如果你想要更详细的解释/例子,请告诉我。)
答案 2 :(得分:0)
CPU比磁盘访问快。一个技巧是gzip你的文件并从中读取。
import gzip
with gzip.open('input.gz','r') as fin:
for line in fin:
print('got line', line)