numpy:停止 numpy.array() 尝试协调元素。从列表创建 ndarray 而不尝试合并/协调元素
numpy: Stop numpy.array() from trying to reconcile elements. Create ndarry from list without trying to merge / reconcile the elements
我在一个列表中有两个二维矩阵,我想将其转换为一个 numpy 数组。下面是 3 个示例 a,b,c .
>>> import numpy as np
>>> a = [np.zeros((3,5)), np.zeros((2,9))]
>>> np.array(a)
>>> array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
>>> b = [np.zeros((3,5)), np.zeros((3,9))]
np.array(b)
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm 2019.2.4\helpers\pydev\_pydevd_bundle\pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "<input>", line 1, in <module>
ValueError: could not broadcast input array from shape (3,5) into shape (3)
>>> c = [np.zeros((3,5)), np.zeros((4,9))]
np.array(c)
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
可以观察到案例 a & c 有效,但 b 无效。 b 确实抛出异常。不同之处在于,在示例 b 中,2 个矩阵的第一个维度匹配。
我发现了以下 ,它解释了为什么会出现这种情况。
If only the first dimension does not match, the arrays are still matched, but as individual objects, no attempt is made to reconcile them into a new (four dimensional) array.
我的问题:我不想让 numpy 协调矩阵。我只想要与第一个维度不匹配时相同的行为。我希望它们 作为独立对象进行匹配,即使 它们具有 相同的第一个维度 。我该如何实现?
即使您明确将 object
作为数据类型传递,Numpy 仍然会报错:
>>> np.array(b, dtype=object)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not broadcast input array from shape (3,5) into shape (3)
本质上,numpy
并不是真正围绕使用 dtype=object
编写的,它总是假定您想要一个具有原始数字或结构化 dtype 的数组。
所以我认为你唯一的选择是:
>>> arr = np.empty(len(b), dtype=object)
>>> arr[:] = b
>>> arr
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
为了好玩,您可以使用实际的 np.ndarray
类型构造函数,尽管这不是很容易:
>>> np.ndarray(dtype=object, shape=len(b), buffer=np.array(list(map(id, b)),dtype=np.uint64))
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
请注意,这依赖于 CPython 实现细节,id
只是 python 对象的地址。所以大多数时候我只是为了好玩而展示它。
在最新版本中我们开始看到警告:
In [185]: np.__version__
Out[185]: '1.19.0'
In [187]: np.array([np.zeros((3,5)), np.zeros((2,9))])
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
#!/usr/bin/python3
Out[187]:
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
它仍然使对象成为 dtype 数组。在匹配的第一维情况下,我们收到警告和错误。
In [188]: np.array([np.zeros((3,5)), np.zeros((3,9))])
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
#!/usr/bin/python3
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-188-b6a4475774d0> in <module>
----> 1 np.array([np.zeros((3,5)), np.zeros((3,9))])
ValueError: could not broadcast input array from shape (3,5) into shape (3)
基本上 np.array
作为第一步尝试创建一个多维数值数组。失败它需要两条路线 - 创建一个对象 dtype 数组或失败。细节隐藏在编译代码中。
如果您想完全控制对象数组的创建方式,预分配和赋值是最好的方法。
In [189]: res=np.empty(2,object)
In [191]: res[:] = [np.zeros((3,5)), np.zeros((3,9))]
我在一个列表中有两个二维矩阵,我想将其转换为一个 numpy 数组。下面是 3 个示例 a,b,c .
>>> import numpy as np
>>> a = [np.zeros((3,5)), np.zeros((2,9))]
>>> np.array(a)
>>> array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
>>> b = [np.zeros((3,5)), np.zeros((3,9))]
np.array(b)
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm 2019.2.4\helpers\pydev\_pydevd_bundle\pydevd_exec.py", line 3, in Exec
exec exp in global_vars, local_vars
File "<input>", line 1, in <module>
ValueError: could not broadcast input array from shape (3,5) into shape (3)
>>> c = [np.zeros((3,5)), np.zeros((4,9))]
np.array(c)
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
可以观察到案例 a & c 有效,但 b 无效。 b 确实抛出异常。不同之处在于,在示例 b 中,2 个矩阵的第一个维度匹配。
我发现了以下
If only the first dimension does not match, the arrays are still matched, but as individual objects, no attempt is made to reconcile them into a new (four dimensional) array.
我的问题:我不想让 numpy 协调矩阵。我只想要与第一个维度不匹配时相同的行为。我希望它们 作为独立对象进行匹配,即使 它们具有 相同的第一个维度 。我该如何实现?
即使您明确将 object
作为数据类型传递,Numpy 仍然会报错:
>>> np.array(b, dtype=object)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not broadcast input array from shape (3,5) into shape (3)
本质上,numpy
并不是真正围绕使用 dtype=object
编写的,它总是假定您想要一个具有原始数字或结构化 dtype 的数组。
所以我认为你唯一的选择是:
>>> arr = np.empty(len(b), dtype=object)
>>> arr[:] = b
>>> arr
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
为了好玩,您可以使用实际的 np.ndarray
类型构造函数,尽管这不是很容易:
>>> np.ndarray(dtype=object, shape=len(b), buffer=np.array(list(map(id, b)),dtype=np.uint64))
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
请注意,这依赖于 CPython 实现细节,id
只是 python 对象的地址。所以大多数时候我只是为了好玩而展示它。
在最新版本中我们开始看到警告:
In [185]: np.__version__
Out[185]: '1.19.0'
In [187]: np.array([np.zeros((3,5)), np.zeros((2,9))])
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
#!/usr/bin/python3
Out[187]:
array([array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]),
array([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]])], dtype=object)
它仍然使对象成为 dtype 数组。在匹配的第一维情况下,我们收到警告和错误。
In [188]: np.array([np.zeros((3,5)), np.zeros((3,9))])
/usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
#!/usr/bin/python3
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-188-b6a4475774d0> in <module>
----> 1 np.array([np.zeros((3,5)), np.zeros((3,9))])
ValueError: could not broadcast input array from shape (3,5) into shape (3)
基本上 np.array
作为第一步尝试创建一个多维数值数组。失败它需要两条路线 - 创建一个对象 dtype 数组或失败。细节隐藏在编译代码中。
如果您想完全控制对象数组的创建方式,预分配和赋值是最好的方法。
In [189]: res=np.empty(2,object)
In [191]: res[:] = [np.zeros((3,5)), np.zeros((3,9))]