【问题标题】:numpy, do multiple operations cause intermediate arrays to be created?numpy,多个操作会导致创建中间数组吗?
【发布时间】:2021-08-10 15:18:11
【问题描述】:

我想知道这两个是否等效:

import numpy as np

a = np.arange(100000) + 1

# 1
b = 10 * np.log10(a)

# 2
c = np.empty_like(a)
c = np.multiply(10, np.log10(a, out=c), out=c)

更准确地说,我想知道 numpy 是否找到了某种方法来创建数组b,而无需为日志操作的结果分配和丢弃中间数组。当然,这只对非常大的数组很重要。

【问题讨论】:

  • 是的,是的。如果您在内存限制下工作时正在寻找替代方案,请考虑使用numexpr 来避免中间数组
  • 只是为了澄清一下:“是的,他们这样做”是指他们确实在 #1 的情况下创建了中间数组,对吗?万一不是#2,但我想它有点难看。
  • 在情况 1 中是,在情况 2 中否。
  • 请注意,np.log10(a, out=c); np.multiply(10, c, out=c) 会更简洁,不会令人困惑。

标签: python performance numpy


【解决方案1】:

在计算时间方面,它们似乎大致相似,虽然第一个版本要好一些:

In [1]: import numpy as np

In [2]: a = np.arange(100_000, dtype=float) + 1

In [3]: def f(a):
   ...:     b = 10 * np.log10(a)
   ...:

In [4]: def g(a):
   ...:     c = np.empty_like(a)
   ...:     c = np.multiply(10, np.log10(a, out=c), out=c)
   ...:

In [5]: %timeit f(a)
759 µs ± 52.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [6]: %timeit g(a)
877 µs ± 39.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【讨论】:

  • 有趣的结果。值得理解为什么第一个表现更好。
  • 当然。不过我不知道。老实说,%timeit 的结果在运行之间确实有所不同,有时gf 做得更好。我会说一般来说它们是一样的。
猜你喜欢
  • 2021-04-09
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多