numpy.VisibleDeprecationWarning:从不规则的嵌套序列创建一个 ndarray

问题描述

这是一个我无法理解的行为示例,也许有人可以分享对其背后逻辑的见解:

ccn = np.ones(1)
bbb = 7
bbn = np.array(bbb)
bbn * ccn # this is OK
    array([7.])
np.prod((bbn,ccn)) # but this is NOT
    Traceback (most recent call last):
    File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.2.2\plugins\python-ce\helpers\pydev\_pydevd_bundle\pydevd_exec2.py",line 3,in Exec
    exec(exp,global_vars,local_vars)
  File "<input>",line 1,in <module>
  File "<__array_function__ internals>",line 5,in prod
  File "C:\Users\...\venv\lib\site-packages\numpy\core\fromnumeric.py",line 2999,in prod
    return _wrapreduction(a,np.multiply,'prod',axis,dtype,out,File "C:\Users\...\venv\lib\site-packages\numpy\core\fromnumeric.py",line 87,in _wrapreduction
    return ufunc.reduce(obj,**passkwargs)
numpy.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

为什么?为什么两个数字的简单乘法会出现问题?就形式代数而言,没有维度问题,没有数据类型问题?结果总是也是一个单一的数字,它不可能“突然”变成向量或对象。 prod(a,b) 对于 ab 是标量或 1by1“矩阵”是 MATLAB 或 Octave 不会有问题的东西。

我知道我可以关闭这个错误等等,但为什么它是偶数和错误

解决方法

In [346]: ccn = np.ones(1)
     ...: bbb = 7
     ...: bbn = np.array(bbb)
In [347]: ccn.shape
Out[347]: (1,)
In [348]: bbn.shape
Out[348]: ()
In [349]: np.array((bbn,ccn))
<ipython-input-349-997419ba7a2f>: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
  np.array((bbn,ccn))
Out[349]: array([array(7),array([1.])],dtype=object)

您拥有不同维度的数组,无法合并为一个数值数组。

那个 np.prod 表达式实际上是:

np.multiply.reduce(np.array([bbn,ccn]))

可以从您的回溯中推断出来。

在 Octave 中,两个对象都有形状 (1,1),2d

>> ccn = ones(1)
ccn =  1
>> ccn = ones(1);
>> size(ccn)
ans =

   1   1

>> bbn = 7;
>> size(bbn)
ans =

   1   1

>> [bbn,ccn]
ans =

   7   1

它没有真正的标量;一切都是 2d(即使 3d 也是最后一个维度的软糖)。

使用“原始”Python 输入:

In [350]: np.array([1,[1]])
<ipython-input-350-f17372e1b22d>:1: VisibleDeprecationWarning: ...
  np.array([1,[1]])
Out[350]: array([1,list([1])],dtype=object)

对象 dtype 数组保留输入的类型。

编辑

prod 不是简单的乘法。这是一个归约运算,就像数学中的大圆周率一样。即使在 Octave 中也不是:

>> prod([[2,3],[3;4]])
error: horizontal dimensions mismatch (1x2 vs 2x1)
>> [2,3]*[3;4]
ans =  18
>> [2,3].*[3;4]
ans =

    6    9
    8   12

numpy 等价物:

In [97]: np.prod((np.array([2,3]),np.array([[3],[4]])))
/usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:87: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences...
    return ufunc.reduce(obj,axis,dtype,out,**passkwargs)
ValueError: could not broadcast input array from shape (2,1) into shape (2,)

In [98]: np.array([2,3])@np.array([[3],[4]])
Out[98]: array([18])
In [99]: np.array([2,3])*np.array([[3],[4]])
Out[99]: 
array([[ 6,9],[ 8,12]])

警告和此处的错误是通过尝试从 (np.array([2,[4]])) 创建一个数组而产生的。