且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将numpy中数组元素的所有组合相乘

更新时间:2023-02-10 15:42:33

首先,一种简单(可以说是正确的)方法来完成您想做的事情:使用 numpy.outer(),而不是 numpy.dot()

First, the easy (and arguably "correct") way to do what you want to do: use numpy.outer(), not numpy.dot().

>>> import numpy
>>> t = [3,4]
>>> b = [1,2,3,4]
>>> numpy.outer(t, b)
array([[ 3,  6,  9, 12],
       [ 4,  8, 12, 16]])

此函数计算两个一维数组的按分量乘积-换句话说,它将一个数组的每个元素乘以另一个数组的每个元素-并返回带有结果的2D数组。

This function computes the component-wise product of two 1D arrays - in other words, it multiplies each element of one array by each element of the other array - and returns a 2D array with the results.

鉴于Numpy显示其结果的方式,您可以认为这是在矩形的顶部写第一个矢量,然后

Given the way Numpy displays its results, you can think of this as writing the first vector across the top of a rectangle and the second one down the left side, and filling in a multiplication table.

 |   1   2   3   4
-+----------------
3|   3   6   9  12
4|   4   8  12  16

该函数对向量实现通用的数学运算,称为外部产品,张量产品或Kronecker产品。注意外部乘积不是可交换的。换句话说,根据给定参数的顺序,您将得到不同的结果。将以上结果与此进行比较:

The function implements a common mathematical operation on vectors, called the outer product, tensor product, or Kronecker product. Note that the outer product is not commutative; in other words, you get a different result depending on which order you give the arguments. Compare the above result to this:

>>> numpy.outer(b, t)
array([[ 3,  4],
       [ 6,  8],
       [ 9, 12],
       [12, 16]])

同样,您可以将其描述为在顶部写第一个参数,在第二个参数下写边并相乘:

Again, you can picture this as writing the first argument across the top, second argument down the side, and multiplying:

 |   3   4
-+---------
1|   3   4
2|   6   8
3|   9  12
4|  12  16

Numpy的 dot()函数,另一方面,在应用于一维数组或点积 https://en.wikipedia.org/wiki/Matrix_multiplication rel = noreferrer>矩阵乘法(适用于2D数组),或矩阵乘法的广义版本(适用于高维数组),但我

Numpy's dot() function, on the other hand, implements the dot product when applied to 1D arrays, or matrix multiplication when applied to 2D arrays, or a generalized version of matrix multiplication when applied to higher-dimensional arrays, but I'll ignore that case because it's a little tricky to understand.


  • 对于两个一维数组, dot( )将两个第一个元素相乘,将两个第二个元素相乘,依此类推,然后将它们全部相加,得到一个数字。

  • For two 1D arrays, dot() multiplies the two first elements together, the two second elements together, etc. and adds them all up, resulting in a number.

>>> numpy.dot([1,2,3], [4,5,6])
32

因为 1 * 4 + 2 * 5 + 3 * 6 == 32 。因此,基本上,它迭代每个数组的索引,将对应的元素相乘,然后将它们相加。显然,两个数组必须具有相同的长度。

because 1*4+2*5+3*6 == 32. So basically, it iterates over the indices of each array, multiplies corresponding elements, and adds them up. Clearly, the two arrays must have the same length.

您可以使用类似于 outer()的方式来可视化此数组。 >,但不要沿边缘写入一维数组,而是将它们垂直于边缘写入。您还应该切换顺序,原因稍后会变得很清楚(但这实际上是一种实现选择):将第一个写在左侧,第二个写在顶部。一个示例将演示:

You can visualize this in a similar way to outer(), but instead of writing the 1D arrays along the edge, write them perpendicular to the edge. You should also switch the order, for reasons that will become clear later (but it's really an implementation choice): write the first one on the left and the second one on the top. An example will demonstrate:

         |   4
         |   5
         |   6
---------+----
1   2   3|  32

要计算32,我将单元格上方列中相应位置的元素与它旁边的行。 1 * 4 2 * 5 3 * 6 ,然后将它们全部加起来。

To calculate the 32, I multiplied elements at the corresponding position in the column above that cell and the row next to it. 1*4, 2*5, and 3*6, and then add them all up.

对于两个2D数组, dot()遍历每个数组的一个轴,将对应的元素相乘,并将它们相加。被迭代的轴是第一个数组的最后一个,也是第二个数组的第一个(实际上是倒数第二个)。显然,这两个轴必须具有相同的长度。

For two 2D arrays, dot() iterates over one axis of each array, multiplies corresponding elements, and adds them up. The axis being iterated over is the last one of the first array, and the first one (actually, next-to-last) of the second array. Clearly, these two axes must have the same length.

从图表的角度很容易理解此操作,因此我将直接跳到该位置:假设您想要计算

It's easy to understand this operation in terms of the diagram, so I'll jump right to that: suppose you want to compute the matrix product of

array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9]])

array([[10, 11],
       [12, 13],
       [14, 15]])

依次排列。同样,只需将第一个参数写在矩形的侧面,将第二个参数写在顶部,然后可以像我在1D示例中所做的那样进行乘加运算以填充每个单元格。

in that order. Again, just write the first argument on the side of a rectangle, and the second one over the top, and then you can multiply-and-add to fill in each cell as I did with the 1D example.

          |  10  11
          |  12  13
          |  14  15
----------+--------
 1   2   3|  76  82
 4   5   6| 184 199
 7   8   9| 292 316

因为例如 4 * 10 + 5 * 12 + 6 * 14 == 184

现在,您可能会注意到可以使用 dot()函数与 outer()函数做同样的事情-但您的数组是2D的具有一个长度为1的维。这就是为什么您必须在原始代码示例中跳过一些箍(例如 [:, None] 索引)以使其起作用。而且它也必须是 right 维度:它必须是第一个数组的最后一个维度,以及第二个数组的倒数第二个维度。因此,在您的特定示例中,您要计算 [3,4] [1,2,3,4] ,按此顺序,您需要将第一个列表转换为形状为(2,1)的数组,将第二个列表转换为形状(1,4)。如果这样做,将它们传递给 dot()时,它将有效地构造此图并填写单元格:

Now, you might notice that you can use the dot() function to do the same thing as the outer() function - but your arrays have be 2D and have a dimension of length 1. That's why you had to jump through some hoops (like the [:, None] indexing) in your original code sample to make it work. And it has to be the right dimension too: it has to be the last dimension of the first array, and the next-to-last dimension of the second array. So in your specific example, where you want to compute the outer product of [3,4] and [1,2,3,4], in that order, you need to convert the first list into an array of shape (2,1), and the second list into an array of shape (1,4). If you do that, when you pass them to dot(), it effectively constructs this diagram and fills in the cells:

     |[[ 1,  2,  3,  4]]
-----+------------------
[[3],|   3   6   9  12
 [4]]|   4   8  12  16

我添加了一些括号来帮助您将这些要求与Numpy语法联系起来。

I added some brackets to help you relate these requirements to Numpy syntax.

您要尝试执行的操作,在问题的代码示例中( numpy.dot(t,b)),会对应于此图:

What you were trying to do, in the code sample in your question (numpy.dot(t, b)), would have corresponded to this diagram:

        | [[1],
        |  [2],
        |  [3],
        |  [4]]
--------+------------------
[[3, 4]]|   ?

请参见,当您尝试对此应用乘加过程时,它不会之所以有效,是因为您在一个数组中有两个元素,在另一个数组中有四个元素,并且您无法将它们配对以进行乘法。这就是Numpy向您显示错误的根源。

See, when you try to apply the multiply-and-add procedure to this, it doesn't work, because you've got two elements in one array and four in the other array, and you can't pair them up to do the multiplications. That's the root of the error Numpy shows you.

当您颠倒顺序时, numpy.dot(b,t),您将得到此图:

When you reverse the order, numpy.dot(b, t), you get this diagram:

     |[[ 3,  4]]
-----+----------
[[1],|   3   4
 [2],|   6   8
 [3],|   9  12
 [4]]|  12  16

这确实给您带来了明智的结果,但请注意是否确实是您想要的那个。这是形状为(4,2)的数组,而如果以最直接的方式修复另一个过程,则会得到形状为(1,1)或实际上只是一个数字。在任何给定情况下,这些选项(最多)中只有一个会起作用。似乎logistic 函数>您在评论中发布的截图期望该 dot()函数中出现一个数字;它不适用于更大的矩阵。 (嗯,虽然可以,但是不会按照您的想法做。)

That does give you a sensible result, but be careful about whether it's really the one you want. This is an array of shape (4,2), whereas if you fix up the other procedure in the most straightforward way, you would get a result of shape (1,1), or really, just a number. In any given situation, only one of these options (at most) will work. And it seems like the logistic function in the screenshot you posted in a comment is expecting a single number to come out of that dot() function; it's not going to work with a larger matrix. (Well, it might, but it won't do what you think.)