Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Python将numpy数组写入文件的有效方法_Python_Numpy - Fatal编程技术网

用Python将numpy数组写入文件的有效方法

用Python将numpy数组写入文件的有效方法,python,numpy,Python,Numpy,我处理的数据约为600万,写入文件需要花费大量时间。我如何改进它 以下是我尝试过的两种方法: import numpy as np import time test_data = np.random.rand(6000000,12) T1 = time.time() np.savetxt('test',test_data, fmt='%.4f', delimiter=' ' ) T2 = time.time() print "Time:",T2-T1,"Sec" file3=open('tes

我处理的数据约为600万,写入文件需要花费大量时间。我如何改进它

以下是我尝试过的两种方法:

import numpy as np
import time
test_data = np.random.rand(6000000,12)
T1 = time.time()
np.savetxt('test',test_data, fmt='%.4f', delimiter=' ' )
T2 = time.time() 
print "Time:",T2-T1,"Sec"
file3=open('test2','w')
for i in range(6000000):
    for j in range(12):
        file3.write('%6.4f\t' % (test_data[i][j]))
    file3.write('\n')
T3 = time.time() 
print "Time:",T3-T2,"Sec" 
时间:56.6293179989秒

时间:115.468323946秒


我正在处理至少100个这样的文件,总时间是很多,请帮助。另外,我没有使用.npy或压缩格式编写,因为我需要在matlab中阅读它们并进行进一步处理。

使用pickle怎么样?我发现它更快

import numpy as np
import time
import pickle
test_data = np.random.rand(1000000,12)

T1 = time.time()
np.savetxt('testfile',test_data, fmt='%.4f', delimiter=' ' )
T2 = time.time()
print ("Time:",T2-T1,"Sec")

file3=open('testfile','w')
for i in range(test_data.shape[0]):
    for j in range(test_data.shape[1]):
        file3.write('%6.4f\t' % (test_data[i][j]))
    file3.write('\n')
file3.close()
T3 = time.time()
print ("Time:",T3-T2,"Sec")

file3 = open('testfile','wb')
pickle.dump(test_data, file3)
file3.close()
T4 = time.time()
print ("Time:",T4-T3,"Sec")

# load data
file4 = open('testfile', 'rb')
obj = pickle.load(file4)
file4.close()
print(obj)
输出是

Time: 9.1367928981781 Sec
Time: 16.366491079330444 Sec
Time: 0.41736602783203125 Sec

用泡菜怎么样?我发现它更快

import numpy as np
import time
import pickle
test_data = np.random.rand(1000000,12)

T1 = time.time()
np.savetxt('testfile',test_data, fmt='%.4f', delimiter=' ' )
T2 = time.time()
print ("Time:",T2-T1,"Sec")

file3=open('testfile','w')
for i in range(test_data.shape[0]):
    for j in range(test_data.shape[1]):
        file3.write('%6.4f\t' % (test_data[i][j]))
    file3.write('\n')
file3.close()
T3 = time.time()
print ("Time:",T3-T2,"Sec")

file3 = open('testfile','wb')
pickle.dump(test_data, file3)
file3.close()
T4 = time.time()
print ("Time:",T4-T3,"Sec")

# load data
file4 = open('testfile', 'rb')
obj = pickle.load(file4)
file4.close()
print(obj)
输出是

Time: 9.1367928981781 Sec
Time: 16.366491079330444 Sec
Time: 0.41736602783203125 Sec
几乎总是比
savetxt
快得多。它只是转储原始字节,而不必将它们格式化为文本。它还可以编写更小的文件,这意味着更少的I/O。在加载时,您将获得同样的好处:更少的I/O,并且没有文本解析

下面的所有内容基本上都是
save
优点的变体。如果你看最后的时间,它们都在一个数量级之内,但都比
savetxt
快两个数量级。所以,您可能只对200:1的加速感到满意,而不在乎进一步调整。但是,如果您确实需要进一步优化,请继续阅读


使用
DEFLATE
压缩保存数组。这意味着您浪费了大量CPU,但节省了一些I/O。如果是速度慢的磁盘使您速度变慢,那就是一场胜利。请注意,对于较小的数组,恒定的开销可能会比压缩加速带来的帮助更大,如果使用随机数组,则几乎不可能进行压缩

savez_compressed
也是一种多数组存储。这在这里似乎是不必要的,但是如果你把一个巨大的数组分为,比如说,20个较小的数组,有时速度会明显加快。(尽管我不知道为什么。)代价是,如果您只是
加载
.npz
堆栈
阵列重新组合在一起,您就不会获得连续存储,因此如果这很重要,您必须编写更复杂的代码

请注意,我下面的测试使用了一个随机数组,因此压缩只是浪费了开销。但是针对
zero
arange
进行测试也会产生相反的误导,因此……这是在真实数据上进行测试的东西

另外,我使用的是一台具有相当快的SSD的计算机,因此CPU和I/O之间的权衡可能不像运行在任何机器上那样不平衡


,或分配到stdlib中的阵列,通过直写缓存备份到磁盘。这不应该减少总的I/O时间,但这意味着I/O不会在最后一次发生,而是分散在整个计算中,这通常意味着它可以与繁重的CPU工作并行发生。因此,与其花50分钟计算然后10分钟节省,不如花55分钟计算和节省

这是一个很难以任何合理的方式测试的程序,实际上没有做任何计算,所以我没有麻烦


或者它的一个替代品,比如或。没有理由认为pickle应该比原始数组转储快,但有时它似乎比原始数组转储快

对于一个简单的连续数组,比如我测试中的数组,pickle只是一个与二进制转储完全相同字节的小包装器,因此它只是一个纯粹的开销


为了进行比较,以下是我如何测试每一个:

In [70]: test_data = np.random.rand(1000000,12)
In [71]: %timeit np.savetxt('testfile', test_data)
9.95 s ± 222 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [72]: os.stat('testfile').st_size
Out[74]: 300000000
注意这里使用了
%timeit
。如果您没有使用IPython,请使用stdlib中的
timeit
模块详细地执行相同的操作。使用
time
进行测试有各种各样的问题(如
timeit
文档中所述,但最大的问题是您只进行了一次测试。对于基于I/O的基准测试,这尤其糟糕


这是每一个结果,但是,上面给出的警告,你应该只考虑前两个有意义的。

  • savetxt
    :9.95s,300MB
  • 保存
    :45.8毫秒,96MB
  • savez_compressed
    :360ms,90MB
  • pickle
    :287ms,96MB
几乎总是比
savetxt
快得多。它只转储原始字节,而不必将其格式化为文本。它还写入更小的文件,这意味着更少的I/O。在加载时,您将获得同样的好处:更少的I/O,无需进行文本解析

下面的所有内容基本上都是
save
的优点之外的变体。如果你看最后的时间,它们都在一个数量级范围内,但都比
savetxt
快两个数量级。因此,你可能只会对200:1的加速感到满意,而不在乎尝试使用twea但是,如果您确实需要进一步优化,请继续阅读


使用
DEFLATE
压缩保存阵列。这意味着您浪费了大量CPU,但节省了一些I/O。如果磁盘速度较慢,这是一个胜利。请注意,对于较小的阵列,恒定的开销可能会比压缩加速带来的帮助更大,如果您有一个随机阵列,则几乎没有压缩这是可能的

savez_compressed
也是一种多数组保存。这在这里似乎没有必要,但如果你将一个巨大的数组分为(比如)20个较小的数组,有时速度会快得多。(尽管我不知道为什么。)代价是,如果您只是
加载
.npz
堆栈
数组重新组合在一起,就不会获得连续存储,因此如果这很重要,您必须编写更复杂的代码

请注意,我下面的测试使用了随机数组,因此压缩只是浪费了开销。但是针对
zero
arange
进行测试会产生相反的误导