NumPy数组1.9.2出现ValueError错误:无法将形状为(4,2)的输入数组广播到形状为(4)的数组。

14

以下代码在numpy 1.7.1中可以运行,但在当前版本中会出现值错误。我想知道其根本原因。

    import numpy as np
    x = [1,2,3,4]
    y = [[1, 2],[2, 3], [1, 2],[2, 3]]

    a = np.array([x, np.array(y)])

以下是我在 numpy 1.7.1 中获得的输出结果。

>>>a
array([[1, 2, 3, 4],
       [array([1, 2]), array([2, 3]), array([1, 2]), array([2, 3])]], dtype=object)

但是在1.9.2版本中,同样的代码会产生错误。

    ----> 5 a = np.array([x, np.array(y)])

ValueError: could not broadcast input array from shape (4,2) into shape (4) 

我已经找到了一个可能的解决方案。但是我不知道这是否是最好的选择。

b= np.empty(2, dtype=object)
b[:] = [x, np.array(y)]

>>> b
array([[1, 2, 3, 4],
       array([[1, 2],
       [2, 3],
       [1, 2],
       [2, 3]])], dtype=object)
请提供一个解决方案以实现所需的输出。谢谢。

1
它在1.7.1版本中“工作”时的结果是什么?你期望它做什么? - tmdavison
4
这行代码“a = a = np.array(x) + np.array(y)”是否应该更正为“a = np.array(x) + np.array(y)”?否则会出现“ValueError: setting an array element with a sequence”的错误提示。 - Rory Yorke
你应该使用 np.dstacknp.hstack 完成这个任务。 - soupault
@tom 数组的第一个元素可能是名称,第二个元素可以是值,例如坐标等。我之前使用过numpy数组,它返回了一个numpy数组。 - Manish
你应该立即告诉我们 x 可能是名称。这意味着结果必须是对象数据类型。你的示例让我们走上了错误的道路,试图堆叠列表。 - hpaulj
显示剩余2条评论
1个回答

3

您究竟想要制作什么?我没有1.7版本来测试您的示例。

np.array(x) 会产生一个(4,)数组。np.array(y)会产生一个(4,2)数组。

如评论中所述,在1.8.1版本中,np.array([x, np.array(y)])将生成:

ValueError: setting an array element with a sequence.

我可以制作一个对象数据类型数组,包含列表和数组

In [90]: np.array([x, np.array(y)],dtype=object)
Out[90]: 
array([[1, 2, 3, 4],
       [array([1, 2]), array([2, 3]), array([1, 2]), array([2, 3])]], dtype=object)

我也可以将两个数组连接起来,得到一个(4,3)的数组(其中x为第一列)

In [92]: np.concatenate([np.array(x)[:,None],np.array(y)],axis=1)
Out[92]: 
array([[1, 1, 2],
       [2, 2, 3],
       [3, 1, 2],
       [4, 2, 3]])

np.column_stack([x,y]) 做的是同样的事情。


有趣的是,在 dev 1.9 版本中(我没有安装生产 1.9.2 版本),它可以工作(有点)。

In [9]: np.__version__
Out[9]: '1.9.0.dev-Unknown'

In [10]: np.array([x,np.array(y)])
Out[10]: 
array([[        1,         2,         3,         4],
       [174420780, 175084380,  16777603,         0]])
In [11]: np.array([x,np.array(y)],dtype=object)
Out[11]: 
array([[1, 2, 3, 4],
   [None, None, None, None]], dtype=object)
In [16]: np.array([x,y],dtype=object)
Out[16]: 
array([[1, 2, 3, 4],
   [[1, 2], [2, 3], [1, 2], [2, 3]]], dtype=object)

看起来有一些开发正在进行。

无论如何,从此列表和2d数组创建新数组是模糊的。使用column_stack(假设您想要一个2d整数数组)。


numpy 1.9.0版本说明:

将包含数组的列表转换为数组的性能已得到改进。现在它的速度相当于使用np.vstack(list)。

使用转置的y vstack有效:

In [125]: np.vstack([[1,2,3,4],np.array([[1,2],[2,3],[1,2],[2,3]]).T])
Out[125]: 
array([[1, 2, 3, 4],
       [1, 2, 1, 2],
       [2, 3, 2, 3]])

如果1.7.1版本起作用,并且“x”是字符串名称而不仅仅是像您示例中的整数,那么它可能会生成一个对象数组。

我也遇到了 ValueError: setting an array element with a sequence. 的问题,通过将 dtype 设置为 object 来解决了该问题。我的一个项目是在 numpy 1.7.1 上开发的,在很多地方我们都以上述格式返回结果,其中第一个元素可能是点的名称,第二个元素可以是每个点的坐标。之前我们得到的是一个 numpy 数组,但现在出现了值错误。 - Manish
一个可能的解决方案是不使用numpy数组,而是使用列表,但这将导致我们在很多地方都必须更改实现方式,因为我们已经把返回值作为数组来处理了。但是我想知道一个可以应用于所有地方的解决方法。谢谢。 - Manish
我找到了一个关于numpy的更改的参考,可能是导致你的错误的原因 - np.array已经被重写为将像你这样的情况视为vstack - hpaulj
我已经编辑了我的问题,包括使用先前版本获得的结果,并找到了一个可能的解决方案。您能否请审核一下。谢谢。 - Manish
我对创建一个对象数组的列表进行了一些时间测试。我没有测试过你的方法(将整个列表分配给预定义的数组),但我怀疑它也很快。在这种情况下,它可能是最健壮的方法。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接