ric*_*ich 5 python numpy python-2.7 numpy-broadcasting
我尝试dtype=object使用数组将不同形状的数组的列表存储为数组np.save(我知道我可以腌制该列表,但是我很好奇如何做到这一点)。如果我这样做:
import numpy as np
np.save('test.npy', [np.zeros((2, 2)), np.zeros((3,3))])
Run Code Online (Sandbox Code Playgroud)
有用。但是这个:
np.save('test.npy', [np.zeros((2, 2)), np.zeros((2,3))])
Run Code Online (Sandbox Code Playgroud)
给我一个错误:
ValueError: could not broadcast input array from shape (2,2) into shape (2)
Run Code Online (Sandbox Code Playgroud)
我想首先np.save将列表转换为数组,所以我尝试了:
x=np.array([np.zeros((2, 2)), np.zeros((3,3))])
y=np.array([np.zeros((2, 2)), np.zeros((2,3))])
Run Code Online (Sandbox Code Playgroud)
具有相同的效果(第一个起作用,第二个不起作用。结果x表现为预期的:
>>> x.shape
(2,)
>>> x.dtype
dtype('O')
>>> x[0].shape
(2, 2)
>>> x[0].dtype
dtype('float64')
Run Code Online (Sandbox Code Playgroud)
我还尝试强制使用'object'dtype:
np.array([np.zeros((2, 2)), np.zeros((2,3))], dtype=object)
Run Code Online (Sandbox Code Playgroud)
没有成功。似乎numpy尝试将具有相同一维的数组广播到新数组中,并且意识到它们的形状不同为时已晚。奇怪的是,它似乎只在某一点上起作用了-所以我真的很好奇差异是什么,以及如何正确地做到这一点。
编辑:我之前弄清楚了它的工作情况:唯一的区别似乎是列表中的numpy数组具有另一种数据类型。它适用于dtype('<f8'),但不适用dtype('float64'),我什至不知道有什么区别。
编辑2:我发现了一种非常非Python的方式来解决我的问题,我在这里添加了它,也许有助于理解我想做什么:
array_list=np.array([np.zeros((2, 2)), np.zeros((2,3))])
save_array = np.empty((len(array_list),), dtype=object)
for idx, arr in enumerate(array_list):
save_array[idx] = arr
np.save('test.npy', save_array)
Run Code Online (Sandbox Code Playgroud)
首先要做的事情之一np.save是
arr = np.asanyarray(arr)
Run Code Online (Sandbox Code Playgroud)
所以是的,它正在尝试将您的列表变成数组。
从任意大小的数组或列表构造对象数组很棘手。 np.array(...)尝试创建尽可能高的维度数组,甚至尝试连接输入(如果可能)。最可靠的方法是执行您所做的操作-制作empty数组并填充它。
构造对象数组的一种更紧凑的方法:
In [21]: alist = [np.zeros((2, 2)), np.zeros((2,3))]
In [22]: arr = np.empty(len(alist), dtype=object)
In [23]: arr[:] = alist
In [24]: arr
Out[24]:
array([array([[ 0., 0.],
[ 0., 0.]]),
array([[ 0., 0., 0.],
[ 0., 0., 0.]])], dtype=object)
Run Code Online (Sandbox Code Playgroud)
这是3种情况:
形状匹配的数组合并为3d数组:
In [27]: np.array([np.zeros((2, 2)), np.zeros((2,2))])
Out[27]:
array([[[ 0., 0.],
[ 0., 0.]],
[[ 0., 0.],
[ 0., 0.]]])
In [28]: _.shape
Out[28]: (2, 2, 2)
Run Code Online (Sandbox Code Playgroud)
在第一个维度上不匹配的数组-创建对象数组
In [29]: np.array([np.zeros((2, 2)), np.zeros((3,2))])
Out[29]:
array([array([[ 0., 0.],
[ 0., 0.]]),
array([[ 0., 0.],
[ 0., 0.],
[ 0., 0.]])], dtype=object)
In [30]: _.shape
Out[30]: (2,)
Run Code Online (Sandbox Code Playgroud)
和尴尬的中间情况(甚至可能被描述为错误)。第一个尺寸匹配,但第二个尺寸不匹配):
In [31]: np.array([np.zeros((2, 2)), np.zeros((2,3))])
...
ValueError: could not broadcast input array from shape (2,2) into shape (2)
[ 0., 0.]])], dtype=object)
Run Code Online (Sandbox Code Playgroud)
好像它初始化了一个(2,2,2)数组,然后发现(2,3)不适合。而且当前的逻辑不允许它像在先前场景中那样备份和创建对象数组。
如果要将两个(2,2)数组放入对象数组,则必须使用创建和填充逻辑。
| 归档时间: |
|
| 查看次数: |
842 次 |
| 最近记录: |