Python 将大数据帧输出到CSV文件的最快方法是什么?
对于python/pandas,我发现df.to_csv(fname)以每分钟约1百万行的速度工作。我有时可以将性能提高7倍,如下所示:Python 将大数据帧输出到CSV文件的最快方法是什么?,python,performance,pandas,output,Python,Performance,Pandas,Output,对于python/pandas,我发现df.to_csv(fname)以每分钟约1百万行的速度工作。我有时可以将性能提高7倍,如下所示: def df2csv(df,fname,myformats=[],sep=','): """ # function is faster than to_csv # 7 times faster for numbers if formats are specified, # 2 times faster for strings.
def df2csv(df,fname,myformats=[],sep=','):
"""
# function is faster than to_csv
# 7 times faster for numbers if formats are specified,
# 2 times faster for strings.
# Note - be careful. It doesn't add quotes and doesn't check
# for quotes or separators inside elements
# We've seen output time going down from 45 min to 6 min
# on a simple numeric 4-col dataframe with 45 million rows.
"""
if len(df.columns) <= 0:
return
Nd = len(df.columns)
Nd_1 = Nd - 1
formats = myformats[:] # take a copy to modify it
Nf = len(formats)
# make sure we have formats for all columns
if Nf < Nd:
for ii in range(Nf,Nd):
coltype = df[df.columns[ii]].dtype
ff = '%s'
if coltype == np.int64:
ff = '%d'
elif coltype == np.float64:
ff = '%f'
formats.append(ff)
fh=open(fname,'w')
fh.write(','.join(df.columns) + '\n')
for row in df.itertuples(index=False):
ss = ''
for ii in xrange(Nd):
ss += formats[ii] % row[ii]
if ii < Nd_1:
ss += sep
fh.write(ss+'\n')
fh.close()
aa=DataFrame({'A':range(1000000)})
aa['B'] = aa.A + 1.0
aa['C'] = aa.A + 2.0
aa['D'] = aa.A + 3.0
timeit -r1 -n1 aa.to_csv('junk1') # 52.9 sec
timeit -r1 -n1 df2csv(aa,'junk3',myformats=['%d','%.1f','%.1f','%.1f']) # 7.5 sec
问题:
What are the ways to make the output even faster?
What's wrong with to_csv() ? Why is it soooo slow ?
注意:我的测试是在Linux服务器上的本地驱动器上使用pandas 0.9.1完成的。您的
df_to_csv
功能非常好,只是它做了很多假设,不适用于一般情况
如果它对你有效,那很好,但是要知道它不是一个通用的解决方案。CSV可以包含逗号,那么如果要写入这个元组会发生什么呢<代码>('a,b','c')
pythoncsv
模块将引用该值,以避免出现混淆,并且如果任何值中存在引号,则将转义引号。当然,生成在所有情况下都有效的东西要慢得多。但我想你只有一堆数字
您可以试试这个,看看它是否更快:
#data is a tuple containing tuples
for row in data:
for col in xrange(len(row)):
f.write('%d' % row[col])
if col < len(row)-1:
f.write(',')
f.write('\n')
#数据是一个包含元组的元组
对于数据中的行:
对于X范围内的列(列(行)):
f、 写入(“%d%”行[col])
如果列<列(行)-1:
f、 写入(',')
f、 写入('\n')
我不知道那样会不会更快。如果不是,那是因为完成了太多的系统调用,所以您可能会使用
StringIO
而不是直接输出,然后每隔一段时间将其转储到实际文件中 Lev。熊猫已经将改写为_csv
,大大提高了本地速度。这个过程现在是i/o绑定的,考虑了许多微妙的数据类型问题和引用案例。以下是我们与0.10.1(即将发布的0.11版本)的性能对比结果。这些都在ms
中,比率越低越好
Results:
t_head t_baseline ratio
name
frame_to_csv2 (100k) rows 190.5260 2244.4260 0.0849
write_csv_standard (10k rows) 38.1940 234.2570 0.1630
frame_to_csv_mixed (10k rows, mixed) 369.0670 1123.0412 0.3286
frame_to_csv (3k rows, wide) 112.2720 226.7549 0.4951
因此,对于单个数据类型(例如float),不太宽的吞吐量约为20M rows/min,下面是上面的示例
In [12]: df = pd.DataFrame({'A' : np.array(np.arange(45000000),dtype='float64')})
In [13]: df['B'] = df['A'] + 1.0
In [14]: df['C'] = df['A'] + 2.0
In [15]: df['D'] = df['A'] + 2.0
In [16]: %timeit -n 1 -r 1 df.to_csv('test.csv')
1 loops, best of 1: 119 s per loop
使用chunksize。我发现这有很大的不同。如果您手头有内存,请使用好的chunksize(行数)进入内存,然后写一次 2019年,对于这种情况,最好只使用numpy。看看时间安排:
aa.to_csv('pandas_to_csv', index=False)
# 6.47 s
df2csv(aa,'code_from_question', myformats=['%d','%.1f','%.1f','%.1f'])
# 4.59 s
from numpy import savetxt
savetxt(
'numpy_savetxt', aa.values, fmt='%d,%.1f,%.1f,%.1f',
header=','.join(aa.columns), comments=''
)
# 3.5 s
因此,您可以使用numpy将时间缩短两倍。当然,这是以降低灵活性为代价的(与aa.to_csv
相比)
以Python3.7、pandas 0.23.4和numpy 1.15.2为基准(xrange
被range
替换,以使问题中发布的函数在Python3中起作用)
另外,如果需要包含索引,
savetxt
可以正常工作-只需传递df.reset_index().values
并相应地调整格式字符串。我最近刚刚使用内置的to_excel和to_csv DataFrame方法从数据框groupby批量导出大约1.7K个报告,以及部分报告(尤其是较大的文件)出来时已损坏。我现在相当怀疑这些内置过程,并计划为我的工作流自制我自己的导出函数。@DavidMarx您能发布一个损坏文件、数据帧和代码的示例吗?这将极大地帮助我们调试问题。谢谢。这是我为我的办公室构建的一个常用工具。我将看看我是否不能用非workplace-sensitive.FWIW的数据复制这个问题。对于这种类型的数据集,它通常需要支付存储在HDF5中的费用,特别是如果您需要查询,请参阅,我正在尝试输出一个100000*100000数据帧,这需要花费很长时间=(我组合了90多个csv文件,每个文件选择特定的4列,只有3个文件超过20000KB,其他文件在平均10000KB以下,一些文件是零行,然后到_csv,需要17分钟。结果csv是20000KB,这一次有意义吗?我如何优化?@Jeff是默认的chunksize 1还是什么?你使用什么chunksize?它是dn对我来说似乎没有什么区别,即使设置chunksize=500000发现它,它可能是1…@words如果列数>100000,chunksize只有1,否则它是100000//尝试将1600万行写入CSV的列数。使用chunksize=1000000,这将写入速度提高了10倍。使用c5.9xlarge EC2 instanceIm收到以下错误:ValueError:fmt的%formats数量错误:%d、%.1f、%.1f、%.1f、%.1f请确保格式字符串与列的数量相同。答案与问题中的测试用例完全一致,对于其他数据帧,它将需要调整。就其价值而言,pandas to_csv不再落后太多(我在V0.23.4上):timeit(“aa.to_csv('temp.csv',index=False)”,globals=globals(),number=5)
37.9stimeit(“np.savetxt('temp.csv',aa.values,fmt='%d,%.1f,%.1f',header=','。join(aa.columns),comments=''”,globals=globals(),number=5)
33.7s
aa.to_csv('pandas_to_csv', index=False)
# 6.47 s
df2csv(aa,'code_from_question', myformats=['%d','%.1f','%.1f','%.1f'])
# 4.59 s
from numpy import savetxt
savetxt(
'numpy_savetxt', aa.values, fmt='%d,%.1f,%.1f,%.1f',
header=','.join(aa.columns), comments=''
)
# 3.5 s