NumPy使用不同形状但前导尺寸相同的数组保存对象

时间:2020-11-30 21:24:29

I experienced some unexpected behavior of np.save(). Assume, you want to save two numpy arrays into one .npy file (as an object). As long both arrays have the same shape this works without any problem, but when the leading dimension is the same an error occurs. The problem is caused by np.asanyarray(), which is called in np.save() prior saving. It is clear that one could solve this problem by e.g. saving into different files, but I am not looking for another solution, I want to understand this behavior of np.save().

我经历了一些np.save()的意外行为。假设您要将两个numpy数组保存到一个.npy文件中(作为对象)。只要两个阵列具有相同的形状,这都可以毫无问题地工作,但是当前导维度相同时会发生错误。问题是由np.asanyarray()引起的,在保存之前在np.save()中调用。很明显,人们可以通过例如保存到不同的文件,但我不是在寻找另一种解决方案,我想了解np.save()的这种行为。

Here is the code:

这是代码:

import numpy as np
a = np.zeros((10, 5))
b = np.zeros((10, 2))
np.save('test', [a, b])

Causes this error:

导致此错误:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/python3/lib/python3.6/site-packages/numpy/lib/npyio.py", line 509, in save
arr = np.asanyarray(arr)
File "/python3/lib/python3.6/site-packages/numpy/core/numeric.py", line 544, in asanyarray
return array(a, dtype, copy=False, order=order, subok=True)
ValueError: could not broadcast input array from shape (10,5) into shape (10)

When the leading dimension is different there is no problem:

当领先维度不同时,没有问题:

a = np.zeros((9, 5))
b = np.zeros((10, 2))
np.save('test', [a, b])

For me this behavior of np.save is inconsistent and seems to be a bug.

对我来说,np.save的这种行为是不一致的,似乎是一个bug。

1 个解决方案

#1


0  

After seeing the source of asanarray method here (save method calls it internally) I see it tries to make a ndarray of the list which is passed using the array method. Now if they have different dimensions, it is able to to make an ndarray with 2 different elements in it. However, if they have the same leading dimension it tries to broadcast them together into a same ndarray. This is because it by default tries to make a high dimensional output. To get around this you can first make use of the empty method to specify dimensions, then use that to substitute the values like:

在这里看到asanarray方法的源代码后(save方法在内部调用它)我看到它试图创建一个使用数组方法传递的列表的ndarray。现在,如果它们具有不同的尺寸,则能够制作具有2个不同元素的ndarray。但是,如果它们具有相同的前导维度,则会尝试将它们一起广播到同一个ndarray中。这是因为它默认尝试生成高维输出。要解决这个问题,您可以先使用空方法指定维度,然后使用它来替换值,如:

a=np.zeros((10,5))
b=np.zeros((10,2))
c=[a,b]
finalc = np.empty(len(c),dtype=object)
finalc[:]=c
np.save("file",c)

#1


0  

After seeing the source of asanarray method here (save method calls it internally) I see it tries to make a ndarray of the list which is passed using the array method. Now if they have different dimensions, it is able to to make an ndarray with 2 different elements in it. However, if they have the same leading dimension it tries to broadcast them together into a same ndarray. This is because it by default tries to make a high dimensional output. To get around this you can first make use of the empty method to specify dimensions, then use that to substitute the values like:

在这里看到asanarray方法的源代码后(save方法在内部调用它)我看到它试图创建一个使用数组方法传递的列表的ndarray。现在,如果它们具有不同的尺寸,则能够制作具有2个不同元素的ndarray。但是,如果它们具有相同的前导维度,则会尝试将它们一起广播到同一个ndarray中。这是因为它默认尝试生成高维输出。要解决这个问题,您可以先使用空方法指定维度,然后使用它来替换值,如:

a=np.zeros((10,5))
b=np.zeros((10,2))
c=[a,b]
finalc = np.empty(len(c),dtype=object)
finalc[:]=c
np.save("file",c)