【问题标题】:Accessing different cells using numpy.nditer使用 numpy.nditer 访问不同的单元格
【发布时间】:2021-11-24 22:13:42
【问题描述】:

我有以下代码

a1 = 0.5
b0 = 3
ui_delta = np.arange(100000)
for i in range(1, ui_delta.shape[0]):
    ui_delta[i] = b0 * ui_delta[i] + a1 * ui_delta[i-1]

是否可以使用 nditer 或 numpy 的其他指令生成此代码? 我正在尝试加速代码,但我正在使用的值数量非常慢。 谢谢

【问题讨论】:

  • 你确实注意到在某些时候你会拥有像a1***99999 这样的人,对吧?
  • nditer 不会提高性能。
  • 我采用的值是实验性的,只是为了让日常工作更容易。

标签: python arrays numpy iteration series


【解决方案1】:

你如何使用 numba 而不是 numpy 来加快速度。

@nb.njit
def calc():
    a1 = 0.5
    b0 = 3
    ui_delta = np.arange(n)
    for i in range(1, ui_delta.shape[0]):
        ui_delta[i] = b0 * ui_delta[i] + a1 * ui_delta[i-1]
    
    return ui_delta
calc()

使用@nb.njit 大约需要 88.1 毫秒,没有它需要大约 393 毫秒。所以速度提高了 4 倍以上。

【讨论】:

  • 感谢您的回答,但在您的代码中,您并没有考虑在每个循环中我都会更改 ui_data。
  • 例如:在我的代码中结果是 (0,3,7,...,599976,599982,599988)。转到最后一个,599988 = 3*99999 + 599982*0.5(99999是ui_data的最后一个值)
  • @ErnestoAvedilloCarretero 哦,你完全正确。我很抱歉。我会解决的。
  • @ErnestoAvedilloCarretero 我写了一个 numpy 版本,结果比原来的慢。看看我上面的 numba 版本。
  • @ErnestoAvedilloCarretero 您真的对所有值感兴趣还是只对最后一个或几个值感兴趣?对于我的 numpy 版本,我得出了公式的非迭代版本。用它来计算所有值会慢一些,但如果你只想要最后一个值会快得多。
【解决方案2】:

最快和更像 Numpy 的方法是使用 array views
如果您从整个数组的角度来看该过程,您要做的是获取除第一项之外的数组并将其添加到自身但没有最后一项。基本上,您将数组与自身相加,但具有 1 个元素的移位。

Numpy 提供了一个非常方便的功能,称为 views,它允许对数组的一部分进行引用或 view。这意味着,改变 view 中的元素也会改变原始数组。

a1 = 0.5
b0 = 3
ui_delta = np.arange(100000)
ui_delta1 = ui_delta[1:] # choosing all but the first element
ui_delta2 = ui_delta[:-1] # all but the last element
ui_delta1[:] = b0 * ui_delta1 + a1 * ui_delta2 

使用整个数组操作不仅可以简化代码,而且比迭代要快得多。 Numpy 有非常高效的内部数组循环,运行速度非常快,因为它们是在底层用С编写的。阵列越大 - 效率增益越显着。

您的代码在大约 1 秒内执行 上面的代码在大约 0.4 毫秒内执行

【讨论】:

    【解决方案3】:

    非常感谢。 用numby的解决方案,觉得挺好的。 另一方面,我在使用 numpy 时仍然没有找到相同的结果 这是 numpy 解决方案 数组([ 0, 3, 6, ..., 349989, 349992, 349996])

    使用 numby 解决方案,结果是正确的。 数组([ 0, 3, 7, ..., 599976, 599982, 599988], dtype=int64)

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案4】:

    我现在看到你们的 cmets 关于我的回答了。

    我想说的是,以下使用 Numpy 的解决方案仍然不行。

    a1 = 0.5
    b0 = 3
    ui_delta = np.arange(100000)
    ui_delta1 =    ui_delta[1:] # choosing all but the first element    
    ui_delta2 =    ui_delta[:-1] # all but the last element    
    ui_delta1[:] = b0 *    ui_delta1 + a1 * ui_delta2
    

    结果是,

    数组([ 0, 3, 6, ..., 349989, 349992, 349996])

    应该是什么时候

    数组([ 0, 3, 7, ..., 599976, 599982, 599988])

    尽管如此,使用 Numba 的解决方案还是相当不错的。 谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 2021-06-01
      • 1970-01-01
      • 2021-01-08
      • 2018-06-18
      • 2014-07-12
      相关资源
      最近更新 更多