Python 锯齿状/参差不齐的Numpy.array的乘法定义是什么?

Python 锯齿状/参差不齐的Numpy.array的乘法定义是什么?,python,numpy,array-broadcasting,Python,Numpy,Array Broadcasting,我不明白在乘以Numpy.array时会发生什么 例如,使用锯齿(或参差不齐)阵列 我明白了 但是,如果我稍微修改一下 import numpy as np a = np.array([[1,2],[100,200]]) b = np.array([2, 4]) print(a * b) 我明白了 我想找到数组乘法的定义。我认为它是“复制('a'数组列[x])('b'数组索引[x])次”。 如果您的目标是进行乘法运算,请改用NP.dot基本上,numpy数组a*b返回初等乘法运算,乘法运算应如

我不明白在乘以Numpy.array时会发生什么

例如,使用锯齿(或参差不齐)阵列

我明白了

但是,如果我稍微修改一下

import numpy as np
a = np.array([[1,2],[100,200]])
b = np.array([2, 4])
print(a * b)
我明白了

我想找到数组乘法的定义。

我认为它是“复制('a'数组列[x])('b'数组索引[x])次”。
如果您的目标是进行乘法运算,请改用NP.dot

基本上,numpy数组a*b返回初等乘法运算,乘法运算应如下所示

Eg-1

输出:

[[ 5 12] [21 32]]
[[ 5 12] [15 24]]
Eg-2

输出:

[[ 5 12] [21 32]]
[[ 5 12] [15 24]]

您的主要问题是数组
a
不是“正常”数组,因为第二维度不相等。 如果尝试
a.shape
会得到
(2,)
a.dtype
给出
dtype('O')
(表示对象),而
a[0]。dtype
会导致属性错误
“list”对象没有属性“dtype”
。 这意味着您有一个维度为2的numpy数组,每个数组包含一个python列表

你应该查一下,但这不是根本原因。如果在操作过程中数组不匹配,通常打算将大小
1
的维度扩展到更大的值。还有很多,但是文档非常清楚。 对于您的特定问题,只需说广播意味着如果两个数组的维数匹配或其中一个数组的维数为1(从后向前计数,用1填充空值),numpy不会抛出错误

您有两个
(2,)
数组(
a
包含2个列表,
b
包含2个整数),这意味着尺寸合适(无需广播)

这种“错误行为”的其余部分(它不是)与numpy无关,因为在标准python中(由于
a
包含python列表而起作用)将列表乘以标量重复项并附加经常出现的列表

所以


在您的案例中也会发生同样的情况:
a
中的第一个列表乘以
2
,第二个列表乘以
4
np.tensordot
文档中的一个示例可能会有所帮助。它创建字符串的对象数组,并显示
dot
生成字符串复制

对于字符串和列表,
*
表示复制

In [134]: 'abc'*3
Out[134]: 'abcabcabc'
您的阵列:

In [126]: a
Out[126]: array([[1, 2, 3], [100, 200]], dtype=object)
In [127]: b
Out[127]: array([2, 4])
和一个字符串数组(我也可以做
a[:]=['a','B']

元素乘法-复制
a
2和3次的元素

In [130]: a*b
Out[130]: array([[1, 2, 3, 1, 2, 3], [100, 200, 100, 200, 100, 200, 100, 200]], dtype=object)
dot
product-同样的东西,但它对*后面的值进行“求和”——列表的求和是串联的

In [131]: a.dot(b)
Out[131]: [1, 2, 3, 1, 2, 3, 100, 200, 100, 200, 100, 200, 100, 200]
In [132]: c*b
Out[132]: array(['aa', 'BBBB'], dtype=object)
In [133]: c.dot(b)
Out[133]: 'aaBBBB'
字符数组、复制和串联也会发生同样的情况

In [131]: a.dot(b)
Out[131]: [1, 2, 3, 1, 2, 3, 100, 200, 100, 200, 100, 200, 100, 200]
In [132]: c*b
Out[132]: array(['aa', 'BBBB'], dtype=object)
In [133]: c.dot(b)
Out[133]: 'aaBBBB'
在处理对象数据类型数组时,numpy基本上迭代元素并应用该对象的类定义的运算符/方法

a*b
生效

In [147]: [i*j for i,j in zip(a,b)]
Out[147]: [[1, 2, 3, 1, 2, 3], [100, 200, 100, 200, 100, 200, 100, 200]]

numpy版本有点花哨,因为它可以处理多维数组并使用广播。

也就是说,需要数组的形式。是吗?你的第一个例子是行为不端,因为每个列表的长度不一致。是的,但是对于这种行为,可以查看官方文件。我知道这个网站,但我找不到我想要的。第一个例子是行为不端,这可能是我想要的。在我写了我的答案后,我终于理解了你的答案。你设法表达得更简洁了。然而,
np.dot
并没有更好的效果,因为包含列表的数组的潜在问题仍然存在。你可以去那里,那里有精彩的解释,我想你会感兴趣的。你是对的,在这个链接后面有很多很好的答案。然而,它们中没有一个与这个问题相关,这里的问题实际上不是乘法,而是(非常非标准的)锯齿数组。
np.tensordot
有一个字符串复制的例子。
In [131]: a.dot(b)
Out[131]: [1, 2, 3, 1, 2, 3, 100, 200, 100, 200, 100, 200, 100, 200]
In [132]: c*b
Out[132]: array(['aa', 'BBBB'], dtype=object)
In [133]: c.dot(b)
Out[133]: 'aaBBBB'
In [147]: [i*j for i,j in zip(a,b)]
Out[147]: [[1, 2, 3, 1, 2, 3], [100, 200, 100, 200, 100, 200, 100, 200]]