Python 如何将阵列的名称用作文件名?
我的代码正在做一些计算,并将输出保存在多个NumPy数组中 最后,我将输出写入磁盘,我希望使用阵列的名称作为单独的文件名,每个阵列都将写入其中 例如,如果我有以下多维数组Python 如何将阵列的名称用作文件名?,python,arrays,python-3.x,numpy,file-io,Python,Arrays,Python 3.x,Numpy,File Io,我的代码正在做一些计算,并将输出保存在多个NumPy数组中 最后,我将输出写入磁盘,我希望使用阵列的名称作为单独的文件名,每个阵列都将写入其中 例如,如果我有以下多维数组 time = [...] force = [...] pressure = [...] energy = [...] 等等,我也是 for array in [time, force, pressure, energy, ....]: with open(**filename**, 'w') as file:
time = [...]
force = [...]
pressure = [...]
energy = [...]
等等,我也是
for array in [time, force, pressure, energy, ....]:
with open(**filename**, 'w') as file:
pickle.dump(array, file)
但是如何设置文件名,使其采用数组名称
我也经历过许多类似的问题(尽管被问及其他动机)。答案表明数组(或任何变量)名称只是标记,不能像这样检索。但我在这里命名文件的动机似乎是一种真正的需要(至少对我来说),所以我问。如果可能的话,我可能会更喜欢HDF5格式,并将数组名用作不同的数据集。虽然所有这些都可以手动实现,但我们为什么要编码呢?可以使用局部变量的名称获取它们。虽然这通常不是最好的主意。但如果需要: 代码: 测试代码: 结果: 本地示例: 因此,要将此示例放到您的示例中:
for array_name in ['time', 'force', 'pressure', 'energy', ....]:
with open(array_name, 'w') as file:
pickle.dump(locals()[array_name], file)
你可以用。这里有一个例子
# inputs
In [196]: A
Out[196]:
array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])
In [197]: B
Out[197]:
array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
# their dtype
In [198]: A.dtype, B.dtype
Out[198]: (dtype('int64'), dtype('int64'))
# their size
In [199]: A.size, B.size
Out[199]: (16, 16)
# store it as a list of tuples
In [200]: dt = np.dtype([('A', A.dtype, A.size), ('B', B.dtype, B.size)])
# get all arrays
In [201]: dt.names
Out[201]: ('A', 'B')
In [202]: dt['A']
Out[202]: dtype(('<i8', (16,)))
如果我从一组变量中列出一个列表,我就无法检索这些变量的名称。我只能检索引用变量的对象
In [324]: x = np.arange(3)
In [325]: y = np.ones((3,3))
In [326]: alist = [x,y]
In [327]: alist
Out[327]:
[array([0, 1, 2]), array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])]
In [328]: id(x)
Out[328]: 2851921416
In [329]: id(alist[0])
Out[329]: 2851921416
alist[0]
不以任何方式引用变量名“x”
字典是将名称或字符串与对象关联的更好方法:
In [331]: adict = {'x':x, 'y':y}
In [332]: adict['x']
Out[332]: array([0, 1, 2])
有了这样一个字典,我可以用savez
保存这些数组:
In [334]: np.savez('temp', **adict)
In [336]: d = np.load('temp.npz')
In [337]: list(d.keys())
Out[337]: ['y', 'x']
npz
archive包含两个名为:
In [340]: !unzip -l temp.npz
Archive: temp.npz
Length Date Time Name
--------- ---------- ----- ----
200 2018-01-29 23:58 y.npy
140 2018-01-29 23:58 x.npy
--------- -------
340 2 files
该词典在创建HDF5
数据集时也很有用
使用pickle
保存/加载变量(和字典)的一些示例:
下面是一个保存和加载工作区(或其中一部分)的尝试,这与使用MATLAB通常所做的一样:
我根本不会做这件事 相反,我愿意
time = [...]
force = [...]
pressure = [...]
energy = [...]
file_data = {'time': time, 'force': force, 'pressure': pressure, 'energy': energy}
for filename, array in file_data.items():
with open(filename, 'w') as file:
pickle.dump(array, file)
这并不能保证3.6之前的订单是正确的,但我认为在这种情况下,订单并不重要
如果秩序重要,我会做的
file_data = [('time', time), ('force', force), ('pressure', pressure), ('energy', energy)]
for filename, array in file_data:
with open(filename, 'w') as file:
pickle.dump(array, file)
您希望以哪种格式保存文件?你的意思是数组名应该是文件名,数组元素是文件内容吗?文件格式无关紧要。我现在正在酸洗,但可以稍后再进行其他酸洗。但是是的,我需要数组名作为文件名,数组元素作为数据进入文件。谢谢。在我寻找答案的时候,我确实发现有人提到使用locals()。但如果可能的话,寻找更优雅的解决方案。无论如何,我希望在测试代码中检索x,y,z,而不是1,2,3。我想需要一些调整?可能是我在你的代码中遗漏了什么。但是我需要文件名中变量的“名称”,而不是它们的“值”。这就是问题所在。您的代码将给出与此相同的结果。。对于(x,y,z)中的i:print(i),我将示例转换为更接近您的代码的内容。这似乎是可行的。但是你不认为为我所有的数组键入一行
dt=np.dtype([('A',A.dtype,A.size),('B',B.dtype,B.size)])
会比我只是在一个列表中手动键入它们的名字要占用更多的空间,比如['time',force',pressure',energy',…]
@nsk我明白你的意思了:)实际上,你可以忽略大小。它将从变量名中推断出来。。但是,我觉得这比把所有的名字都作为一个字符串放在一个列表中要干净一点。是的,但是如果我跳过*.dtype和np.dtype,我就只剩下字符串列表了P谢谢你的回答。我学到了一个新东西。这似乎是我可以使用的东西。我将不得不修改我的主数学程序,并将numpy数组写入字典,而不是单个数组。你认为这会对内存使用和速度产生(额外)影响吗,因为我的数据很大。这些阵列是多维的,文件大小已经很容易达到1.5GB。这是@hpaulj建议的,我想我会这么做。但是也应该有一种简单的方法来检索名称,因为当for循环读取它时,它首先按名称读取数组,然后查找它们的值。
In [334]: np.savez('temp', **adict)
In [336]: d = np.load('temp.npz')
In [337]: list(d.keys())
Out[337]: ['y', 'x']
In [340]: !unzip -l temp.npz
Archive: temp.npz
Length Date Time Name
--------- ---------- ----- ----
200 2018-01-29 23:58 y.npy
140 2018-01-29 23:58 x.npy
--------- -------
340 2 files
time = [...]
force = [...]
pressure = [...]
energy = [...]
file_data = {'time': time, 'force': force, 'pressure': pressure, 'energy': energy}
for filename, array in file_data.items():
with open(filename, 'w') as file:
pickle.dump(array, file)
file_data = [('time', time), ('force', force), ('pressure', pressure), ('energy', energy)]
for filename, array in file_data:
with open(filename, 'w') as file:
pickle.dump(array, file)