【问题标题】:python numpy: iterate for different conditions without using a looppython numpy:在不使用循环的情况下迭代不同的条件
【发布时间】:2017-12-09 23:35:18
【问题描述】:

我正在尝试遍历 numpy 数组并生成一个输出,其条件类似于以下描述:

min1 = 3
max1 = 1
a1 = np.array([1, 2, 5, 3, 4])
a2 = np.array([5, 2, 6, 2, 1])
output = np.zeros(5)
for i in range(0, 5):
  if((a1[i] - a2[i]) > min1):
    output[i] = 3 * (a1[i] - a2[i])

  if((a1[i] - a2[i]) < max1):
    output = 5 * (a1[i] - a2[i])

我需要优化上面的代码,以便最好地利用numpy 功能并避免使用循环。我该怎么做?

【问题讨论】:

  • 你为什么在这里循环??
  • 不知道为什么@Sanober 的完美功能编辑被拒绝了。我只是手动重做了他的工作。

标签: python arrays numpy optimization


【解决方案1】:

欢迎来到 SO!首先,问题提示:

  1. 即使您当前的循环代码也不起作用,因为您将值分配给 output 而不是 output[i]。尝试确保如果您要求进行代码重构,您的原始代码可以正常工作(除了numpy 标签之外,要求对 SO 进行代码重构通常会让您被否决)。

  2. 你会想要这样一个嵌套的np.where 语句

    output = np.where((a1 - a2) > min1, 3 * (a1 - a2), (np.where((a1 - a2) < max1, 5 * (a1 - a2), 0)))
    

这样你就不需要初始化output,也没有更多的循环代码。

如果条件很多,也可以使用np.select

d = a1 - a2
condlist = [d > min1, d < max1]
choicelist = [3 * d, 5 * d]
output = np.select(condlist, choicelist)

【讨论】:

  • 这也有效!谢谢!我会记住这些提示!
【解决方案2】:

你的问题有点含糊。这是一个可能的解决方案,具体取决于您的实际需求。

此解决方案将返回 2 个数组,其中包含属于您指定的最小值和最大值的值。它的作用是它对你的两个数组执行- 操作,而不是执行 if,numpy 有一个名为 where 的函数,它会为你执行此操作,而无需遍历整个数组。

import numpy as np
min1=3
max1=1
a1=np.array([1,2,5,3,4])
a2=np.array([5,2,6,2,1])
array_op = a1-a2
min_output = 3*(array_op[np.where((array_op)>min1)])
max_output = 5*(array_op[np.where((array_op)<max1)])

【讨论】:

    【解决方案3】:

    a1[i]-a2[i] 运算在一次迭代中完成 4 次 将其保存为变量以节省 3*5 = 15 次计算

    【讨论】:

    • 如果您没有完整的答案,请发表评论。一旦获得足够的声望,您就可以发表评论了。
    【解决方案4】:

    虽然像selectwhere 这样的函数可以压缩代码,但我认为知道如何使用基本的布尔掩码来做到这一点是个好主意。它适用于许多情况,而且几乎总是一样快。

    计算多次使用的差值:

    In [432]: diff = a1-a2
    In [433]: diff
    Out[433]: array([-4,  0, -1,  1,  3])
    In [435]: output = np.zeros_like(a1)
    

    找出满足第一个条件的那些情况,设置output的对应元素:

    In [436]: mask1 = diff>min1
    In [437]: output[mask1] = 3*diff[mask1]
    

    重复第二个条件:

    In [438]: mask2 = diff<max1
    In [439]: output[mask2] = 5*diff[mask2]
    

    如果有更多条件,再重复一次。

    In [440]: output
    Out[440]: array([-20,   0,  -5,   0,   0])
    

    在这个例子中,只有 -4 和 -1 满足条件 2,没有条件 1。

    【讨论】:

      【解决方案5】:

      解决办法是

          import numpy as np
          min1=3
          max1=1
          a1=np.array([1,2,5,3,4])
          a2=np.array([5,2,6,2,1])
      
          output=np.zeros(5)
          diff = a1-a2
      
          output[np.where(diff < max1)] = diff[np.where(diff < max1)]*5
          output[np.where(diff > min1)] = diff[np.where(diff > min1)]*3
      

      【讨论】:

        猜你喜欢
        • 2020-08-07
        • 2017-03-25
        • 1970-01-01
        • 2020-03-19
        • 2020-02-26
        • 1970-01-01
        • 2013-03-29
        • 2023-02-26
        • 1970-01-01
        相关资源
        最近更新 更多