如何在不丢失精度的情况下将连续调用附加到单个 numpy 文件?

How to append successive calls to a single numpy file without losing precision?

在应用一些程序后,我得到了数百万个 numpy 数组(在下面的例子中,程序将 e 转换为 numpy 数组):

for e in l:
    procedure(e)

如何将每次迭代正确地保存到单个 numpy 文件中以供以后读取和加载?

到目前为止,我尝试了两个选项,np.savez:

for i, e in enumerate(l):
    np.savez(f'/Users/user/array.npz',i=e)

与 pandas:

(1) 保存到单个文件:

for e in l:
   arr = pd.DataFrame(procedure(i)).T 
   arr.to_csv('/Users/user/Downloads/arr.csv', mode='a', index=False, header=False)

(2) 阅读:

arr = np.genfromtxt("/Users/user/Downloads/arr.csv", delimiter=',', dtype='float32', float_format='%.16f')

到目前为止,有效的解决方案是 pandas。但是,我想我在 numpy 矩阵中失去了 presicion。因为不是像这样的值(带有 e):

-6.82821393e-01 -2.65419781e-01

我得到这样的值:

-0.6828214 , -0.26541978

但是,numpy 矩阵没有正确保存。

在 for 循环迭代后将每个 numpy 矩阵转储到单个文件中的最有效和正确的方法是什么?

np.savez 以 zip 样式格式保存数组,默认名称为 arr_0。如果您再次使用它,它将覆盖您当前的文件,这意味着最新的文件将在保存后在那里。好处是您可以在 zip 中命名文件,因此您可以为每个 numpy 数组使用自定义名称,或者只是索引,如下例所示。

for i, e in enumerate(l):
 np.savez(f'/Users/user/array.npz',i=e)

我不知道在这种情况下 csv 格式是否正确,但您可以指定 float 格式以避免精度损失。

使用 pandas

附加到 CSV
import pandas as pd
import numpy as np
pd.set_option('precision', 16)  # for print command

fn = 'pandasfile.csv'
arr = np.linspace(1,100,10000).reshape(5000,2)
df = pd.DataFrame(arr)

df.to_csv(fn, mode='a', index=False, header=False, float_format='%.16f', sep='\t')

使用 numpy 附加到 CSV

import numpy as np
np.set_printoptions(precision=16)

fn = 'numpyfile.csv'
arr = np.linspace(1,100,10000).reshape(5000,2)
print(arr)

with open(fn, "a") as f:
    np.savetxt(f, arr, fmt='%.16f', delimiter='\t')

我用制表符作为分隔符,这样更易​​读(有人称它为TSV文件)。您可以使用 "," 或 " " 代替。

将 CSV 加载到 numpy

arr2 = np.loadtxt(fn, delimiter='\t')
print(arr2)

将 CSV 加载到 pandas

df = pd.read_csv(fn, header=None, sep='\t', dtype='float32')
print(df)

如果重要,Numpy 版本会更快一些。

m@o780:~$ time python3 pdsave.py 

real    0m0,473s
user    0m0,448s
sys 0m0,102s

m@o780:~$ time python3 npsave.py 

real    0m0,199s
user    0m0,214s
sys 0m0,072s
m@o780:~$