为啥我不能将一个 numpy 数组除以(或乘以)一个标量?

Posted

技术标签:

【中文标题】为啥我不能将一个 numpy 数组除以(或乘以)一个标量?【英文标题】:Why can't I divide (or multiply) a numpy array of arrays by a scalar?为什么我不能将一个 numpy 数组除以(或乘以)一个标量? 【发布时间】:2021-11-11 15:01:07 【问题描述】:

我正在研究我生命中的第一个基于代理的模型 (abm),我必须对一组数组进行操作。我的模型的每个代理都是一个数组,其中包含在满足某些条件时由算法添加的数字。有时我必须将所有数组除以或乘以相同的数字。我在 numpy 数组中看到我可以这样做:

vector = np.array([1, 2.1, 3])

当我这样做时

2 / vector

正如预期的那样,给了我array([ 2. , 0.95238095, 0.66666667])

但是如果我想要一个数组,例如

arrayofarrays = np.array([[1,2,3],[1.1,6],[1]])

默认情况下它有dtype=object,我想这是不允许我这样做的

2 / arrayofarrays

给了

unsupported operand type(s) for /: 'int' and 'list'

还有

2 / arrayofarrays[0]

给出同样的错误。 相反,如果您使用单个数组的值,则为

2/arrayofarrays[0][1]

有效:1.0

你能帮帮我吗?谢谢

【问题讨论】:

您的arrayofarrays 实际上是一个列表数组。 Python 列表不支持算术。 谢谢。那我该怎么办? 可能有更好的方法,但你可以这样做arrayofarrays = np.array([np.array(x) for x in [[1,2,3],[1.1,6],[1]]]) Numpy 不是 Python! Python 有列表列表,内部列表允许有不同的长度。另一方面,numpy 使用多维数组。不同之处在于所有元素的基本类型应该是相同的(numpy dtype),并且所有相同级别的子数组应该具有相同的大小。如果满足这些条件,并且 dtype 是数字,则 numpy 允许在整个数组或内部数组上广播操作(如果尺寸匹配)。由于您有一个具有 object dtype 的 numpy 数组,因此它仅支持对象操作(意味着根本没有操作...) @SergeBallesta,使用对象 dtype 数组,numpy 尝试将运算符应用于每个元素。结果取决于元素的类别。这是以列表理解速度完成的。 【参考方案1】:

你的参差不齐的数组 - 一个列表数组:

In [31]: arr = np.array([[1,2,3],[1.1,6],[1]])
<ipython-input-31-4887f672b831>: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.
  arr = np.array([[1,2,3],[1.1,6],[1]])
In [32]: arr
Out[32]: array([list([1, 2, 3]), list([1.1, 6]), list([1])], dtype=object)

对象 dtype 数组的数学运算是逐个元素执行的(以列表理解速度)。它的工作原理取决于相应的方法如何工作元素:

In [33]: arr *2
Out[33]: 
array([list([1, 2, 3, 1, 2, 3]), list([1.1, 6, 1.1, 6]), list([1, 1])],
      dtype=object)

list*2 是复制操作,而不是乘法。

In [34]: arr / 2
Traceback (most recent call last):
  File "<ipython-input-34-855a165721c4>", line 1, in <module>
    arr / 2

没有为列表定义除法。

TypeError: unsupported operand type(s) for /: 'list' and 'int'

我们可以用frompyfunc对每个元素应用一个简单的函数:

In [38]: np.frompyfunc(lambda x: np.array(x)/2, 1,1)(arr)
Out[38]: 
array([array([0.5, 1. , 1.5]), array([0.55, 3.  ]), array([0.5])],
      dtype=object)

此函数负责转换为数组以及除法。

等效的列表理解(同样快):

In [40]: [np.array(x)/2 for x in arr]
Out[40]: [array([0.5, 1. , 1.5]), array([0.55, 3.  ]), array([0.5])]

或纯列表版本(可能更快)

In [41]: [[y/2 for y in x] for x in arr.tolist()]
Out[41]: [[0.5, 1.0, 1.5], [0.55, 3.0], [0.5]]

【讨论】:

感谢您的回答。但现在我真的很困惑:我不明白为什么2 / vector(我的例子)工作正常!似乎如果 np.array 只是一个可以乘除的数组,否则就不行 arrayofarrays[0] 是一个列表。 arrayofarrays[0][1] 是一个数字。 vector=np.array([1, 2.1, 3])2/vector 有效。而不是arr = np.array([[1,2,3],[1.1,6],[1]])2/arr 不是 好吧……也许我现在开始明白了……有些东西实际上是不同的,但我认为它们是一样的:可以创建一个列表列表,也可以创建一个np.array 的列表或 np.arrays 的 np.array。例如,我做了一些测试,发现test = np.array([ np.array([1,2,3]), np.array([1.1,6]), np.array([1]) ])dtype=object,但它与2/test 一起工作正常 Object dtype arays 可以保存任何东西,列表、数组、数字、字符串等。此类数组上的数学以 python 迭代速度将操作委托给元素。它是否有效是命中注定的。

以上是关于为啥我不能将一个 numpy 数组除以(或乘以)一个标量?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 int numpy 数组的列乘以浮点数并保持在 int 中?

Numpy:将每一行除以一个向量元素

动态归一化二维 numpy 数组

为啥 Numpy 掩码数组有用?

python怎么实现矩阵的除法

python使用numpy的np.mod函数计算numpy数组除以某一特定数值剩余的余数(remainder)np.mod函数和np.fmod函数对负值的处理方式有差异