【问题标题】:How to calculate two different numpy array's values then put the result in a third array如何计算两个不同的 numpy 数组的值,然后将结果放入第三个数组
【发布时间】:2019-05-07 16:10:47
【问题描述】:

我需要计算两个 numpy 数组以获得第三个数组所需的行为。

首先,这是前两个数组:

[[2 0 1 3 0 1]
 [1 2 1 2 1 2]       # ARRAY 1
 [2 1 2 1 0 1]
 [0 2 0 2 2 3]
 [0 3 3 3 1 4]
 [2 3 2 3 1 3]]

[[0.60961197 0.29067687 0.20701799 0.79897639 0.74822711 0.21928105]
[0.67683562 0.14261662 0.74655501 0.21529103 0.14347939 0.42190162]
[0.21116134 0.98618323 0.93882545 0.51422862 0.12715579 0.18808092]    # ARRAY 2
[0.48570863 0.32068082 0.32335023 0.62634641 0.37418013 0.44860968]
[0.12498966 0.56458377 0.24902924 0.12992352 0.76903935 0.68230202]
[0.90349626 0.75727838 0.14188677 0.63082553 0.96360265 0.28694261]]

其中 array1[0][0] 将用于从 array3[0][0] 中减去输入值,然后使用 array2[0][0] 将现在从 array3[0 中减去的值相乘][0] 给出 array3[1][0] 的新输出(换句话说,这些计算将得到 array3)。

例如,假设 array3[0] 的起始值为:

[[20,22,24,40,42,10],
  ....

对于array3[0][0] (20),它需要减去2(来自array1[0][0]),留下18的值。然后现在乘以18 0.60961197 (array2[0][0]) 留下 NEW VALUE 10.9710.97 现在是 array3[1][0] 的新值。

如果您要移动到下一列,过程将是相同的。您将取 22-0 = 22,然后取 22 * 0.29067687 为 array3[1][1] 创建新值。

为了提供一个直观的例子,前两行的这个数组的完整过程如下所示:

      [[20 22 24 40 42 10],
     [10.97  19.65 7.44 10.58 7.03],
      ....

我试图让这个过程在第一个数组的整个长度上继续进行(我猜是第二个,因为它们是相同的)。因此,对于下一组,您将为每个索引取 10.97-1 * 0.6768... = 6.74.. 以此类推,直到它到达末尾。

我很困惑该怎么做,我尝试了一个 for 循环,但我觉得在 numpy 中可能有更多有效的方法来做到这一点。

衷心感谢您的帮助,我知道这并不容易(或者可能会!)。这将启动对我来说将是一个相当漫长的项目。

非常感谢!

注意:如果 numpy 数组不是解决此问题的好方法,并且可以说列表更好,我非常愿意走这条路。我只是假设大多数 numpy 的功能会更容易。

【问题讨论】:

  • 可以添加array3吗?
  • 将 array3 添加到什么?喜欢完成数组?
  • array3的起始值
  • 如果你不想做解析数学,你可以简单地在for i in range(len(array1))中做array3[i+1]=(array3[i]-array1[i])*array2[i]
  • 计算array3的起始值不会真正改变任何东西@DanielMesejo,因为array3的功能只是得到array1和2的计算结果

标签: python arrays numpy


【解决方案1】:

只是将我的评论扩展为完整的答案。问题是在谈论两种“重复”:

  • 并行可行(按列、可广播)
  • 并行不可行(逐行、迭代)

numpy 很好地处理广播(即列方向),所以只需在行方向上使用 for 循环:

for i in range(len(array1)):
    array3[i+1] = (array3[i] - array1[i]) * array2[i]

请注意array3 应该比array1array2 长,否则没有意义。

编辑

糟糕,我没有看到你想避免 for 循环。从技术上讲,你可以在没有 for 循环的情况下解决这个问题,但你需要自己搞乱线性代数:

如果我们将array1 命名为a,将array2 命名为b,将array3 的第一行命名为c,以方便起见。 array3 的行将是:

  • c
  • (c-a0)*b0 = c*b0-a0*b0
  • ((c-a0)*b0-a1)*b1 = c*b0*b1-a0*b0*b1-a1*b1
  • ...

array3 的最后一行可以计算为

B = b[::-1].cumprod(0)[::-1]
final_c = c * B[0] - (B * a).sum(0)

如果你想要整个 array3,那么没有 for 循环就不是那么简单了。您也许可以编写它,但这既读起来又痛苦,写起来也很痛苦。性能也值得怀疑

【讨论】:

  • 我对循环没有问题,我只是想这可能可以用另一个 numpy 函数来解决!正如你所说,我认为没有循环几乎是不可能的哈哈
  • 如果numpy提供一个计算“累积乘积三角形”的函数(即计算数组中任意两点之间的累积乘积并返回一个矩阵的函数)会更简单
  • 有没有一个你知道的模块可以提供它?就像我说的那样,我并没有死心塌地在 numpy 或数组上,只要能提供一个很好的简单解决方案,我都会全力以赴!
【解决方案2】:

如果我理解正确,你可以这样做:

import numpy as np

np.random.seed(42)

arr1 = np.array([[2, 0, 1, 3, 0, 1],
                 [1, 2, 1, 2, 1, 2],
                 [2, 1, 2, 1, 0, 1],
                 [0, 2, 0, 2, 2, 3],
                 [0, 3, 3, 3, 1, 4],
                 [2, 3, 2, 3, 1, 3]])

arr2 = np.array([[0.60961197, 0.29067687, 0.20701799, 0.79897639, 0.74822711, 0.21928105],
                 [0.67683562, 0.14261662, 0.74655501, 0.21529103, 0.14347939, 0.42190162],
                 [0.21116134, 0.98618323, 0.93882545, 0.51422862, 0.12715579, 0.18808092],
                 [0.48570863, 0.32068082, 0.32335023, 0.62634641, 0.37418013, 0.44860968],
                 [0.12498966, 0.56458377, 0.24902924, 0.12992352, 0.76903935, 0.68230202],
                 [0.90349626, 0.75727838, 0.14188677, 0.63082553, 0.96360265, 0.28694261]])

arr3 = np.random.randint(5, 30, size=(6, 6))

result = (arr3 - arr1) * arr2

print(result)

输出

[[ 5.48650773  6.97624488  3.72632382  9.58771668  8.97872532  5.2627452 ]
 [ 6.7683562   2.99494902 19.41043026  2.79878339  2.00871146 10.96944212]
 [ 4.85671082  6.90328261  9.3882545  13.88417274  0.89009053  4.702023  ]
 [12.14271575  1.28272328  9.05380644  8.76884974  2.99344104  1.34582904]
 [ 3.1247415   1.12916754  3.23738012  2.98824096 11.53559025 17.0575505 ]
 [17.16642894  8.33006218  2.55396186 10.09320848 17.3448477   5.7388522 ]]

如果应用于您示例中的数据,您会得到:

arr3 = np.array([20, 22, 24, 40, 42, 10])
result = (arr3 - arr1[0]) * arr2[0]
print(result)

输出

[10.97301546  6.39489114  4.76141377 29.56212643 31.42553862  1.97352945]

请注意,在第二个示例中,我只使用arr2arr3 中的第一行。

【讨论】:

  • 那么是否可以采用您为我的示例提供的输出,应用计算公式,然后对 array1 的长度重复该过程?
  • @LandonG 不需要,第一个示例适用于所有行。 -* 运算符在 numpy 中是逐元素的
  • 但是结果(如果我正确理解您的方法)不应该达到负值吗?例如,我运行了你的方法,在第二行之后,我计算了 array3[1][5] - 0.0126,但输出有 3.37(即:1.97...-2 * 0.42190...)
  • 我相信不是,在第一个示例中,所有值都是在 5 到 30 之间随机生成的,并且 5 大于 arr1 (4) 中较大的元素。所以所有的值都应该是正的
猜你喜欢
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
相关资源
最近更新 更多