当前位置:  开发笔记 > 编程语言 > 正文

将所有数组元素组合乘以numpy

如何解决《将所有数组元素组合乘以numpy》经验,为你挑选了1个好方法。

注意:我对"只使用for for循环"这个形式的答案不感兴趣,我想以笨拙的方式做到这一点.

我是Python的初学者,我想使用numpy ndarray执行以下操作:给定一个数字t序列和另一个数字序列b,对于每个t[i]我想要计算列表t[i]*b并将其存储为最终数组中的新行.例:

t = [3,4]
b = [1,2,3,4]

然后结果应该是某种形式的列表编码

[
  [3,6,9,12], # 3 * the array of b's
  [4,8,12,16]   # 4 * the array of b's
]

在我最近看到的一个程序中,这完全成功,但是当我想自己做的时候,它会引发一个错误:运行

import numpy

t = numpy.linspace(3,4,2)[:, None]
t = t.T

# filled with some garbage numbers
b = numpy.ndarray(shape=(4,1), dtype=numpy.float64, order='C')

res = numpy.dot(t,b)

在python(版本3.4)给出

Traceback (most recent call last):
  File "C:\Daten\LiClipse_workspace\TestProject\MainPackage\PlayGround.py", line 9, in 
    res = numpy.dot(t,b)
ValueError: shapes (1,2) and (4,1) not aligned: 2 (dim 1) != 4 (dim 0)

题:

如何使这项工作?



1> David Z..:

首先,简单(并且可以说是"正确")的方式来做你想做的事:使用numpy.outer(),而不是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]])

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

考虑到Numpy显示结果的方式,您可以将其视为在矩形顶部写入第一个向量,在左侧写入第二个向量,并填充乘法表.

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

该函数对向量实现了一个常见的数学运算,称为外积,张量积或Kronecker积.请注意,外部产品不是可交换的; 换句话说,根据您给出参数的顺序,您会得到不同的结果.将上述结果与此进行比较:

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

再次,您可以将此描述为在第一个参数中写入第一个参数,第二个参数在旁边,并乘以:

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

dot()另一方面,Numpy的功能在应用于1D阵列时实现点积,或在应用于2D阵列时实现矩阵乘法,或在应用于更高维数组时实现矩阵乘法的通用版本,但我会忽略这种情况,因为理解它有点棘手.

对于两个1D阵列,dot()将两个第一个元素相乘,将两个第二个元素相乘,等等,并将它们全部加起来,得到一个数字.

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

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

您可以以类似的方式将其可视化outer(),但不是沿着边缘写入1D阵列,而是将它们垂直于边缘写入.您也应该切换订单,原因稍后会变得清晰(但它确实是一个实现选择):在左边写第一个,在顶部写第二个.一个例子将证明:

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

为了计算32,我将该单元格上方列中相应位置的元素与其旁边的行相乘.1*4,, 2*53*6,然后将它们全部添加.

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

从图中可以很容易地理解这个操作,所以我会直接去那个:假设你想要计算矩阵乘积

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

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

以该顺序.再次,只需在矩形的一侧写下第一个参数,然后在顶部写下第二个参数,然后你就可以乘法和加法来填充每个单元格,就像我在1D示例中所做的那样.

          |  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]索引)原始代码示例使其工作.它也必须是正确的维度:它必须是第一个数组的最后一个维度,以及第二个数组的倒数第二个维度.因此,在您的具体示例中,您想要计算外部产品的位置,[3,4]并且按此[1,2,3,4]顺序,您需要将第一个列表转换为形状数组(2,1),将第二个列表转换为形状数组(1,4).如果你这样做,当你传递它们时dot(),它会有效地构造这个图并填充单元格:

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

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

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

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

当你尝试将乘法和加法过程应用于此时,它不起作用,因为你在一个数组中有两个元素而在另一个数组中有四个元素,你不能将它们配对做乘法.这是Numpy向您展示的错误的根源.

当你颠倒订单时numpy.dot(b, t),你得到这个图:

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

这确实给你一个明智的结果,但要小心它是否真的是你想要的那个.这是一个形状的数组(4,2),而如果你以最直接的方式修复另一个过程,你会得到一个形状的结果(1,1),或者实际上只是一个数字.在任何给定的情况下,这些选项中只有一个(最多)可以工作.而且,您在评论中发布logistic的屏幕截图中的功能似乎是期望从该dot()功能中输出一个数字; 它不适用于更大的矩阵.(好吧,它可能,但它不会做你的想法.)

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有