首页 > 解决方案 > numpy:阻止 numpy.array() 尝试协调元素。从列表中创建 ndarry 而不尝试合并/协调元素

问题描述

我在一个列表中有两个二维矩阵,我想将它们转换为一个 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 个矩阵的第一个维度匹配。

我找到了以下答案,这解释了为什么会发生这种行为。

如果只有第一个维度不匹配,则数组仍然匹配,但作为单独的对象,不会尝试将它们协调为新的(四维)数组。

我的问题:我不希望 numpy 协调矩阵。我只想要与第一个维度不匹配的行为相同的行为。我希望它们作为单个对象匹配,即使它们具有相同的第一维。我该如何做到这一点?

标签: pythonnumpynumpy-ndarrayarray-broadcasting

解决方案


即使您明确地object作为 dtype 传递,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并不是真正围绕 using 编写的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 对象的地址。所以大多数时候我只是为了好玩而展示它。


推荐阅读