【问题标题】:How do I maximize efficiency with numpy arrays?如何使用 numpy 数组最大限度地提高效率?
【发布时间】:2011-03-24 21:12:29
【问题描述】:

我刚刚开始了解 numpy,它声称在其 ndarray 中具有类似 C 的效率以及内存访问给我留下了深刻的印象。我想亲自看看这些和 pythonic 列表之间的区别,所以我运行了一个快速计时测试,在没有它的情况下使用 numpy 执行一些相同的简单任务。正如预期的那样,Numpy 在数组的分配和算术运算方面超过了常规列表一个数量级。但是这段代码在两个测试中都相同,使用常规列表大约需要 1/8 秒,使用 numpy 大约需要 2.5 秒:

file = open('timing.log','w')
for num in a2:
    if num % 1000 == 0:
        file.write("Multiple of 1000!\r\n")

file.close()

有谁知道为什么会这样,如果有其他语法我应该使用这样的操作来更好地利用 ndarray 可以做什么?

谢谢...

编辑:回答韦恩的评论...我以不同的顺序重复计时,每次都得到几乎相同的结果,所以我怀疑这是另一个过程。我放了

start = time()
在 numpy 导入之后的文件顶部,然后我有像
print 'Time after traversal:\t',(time() - start)
这样的语句。

【问题讨论】:

  • 你能说明你是如何测量时间的吗?您是否尝试交换您接受的订单?您正在写入磁盘的事实使时间问题变得复杂(如果[insert-process-here] 在 numpys 测试期间以更高的优先级写入磁盘怎么办?)
  • 感谢所有回复!所有人都提供了丰富的信息。抱歉,我没有足够的声望给他们投票!

标签: python performance numpy


【解决方案1】:

对于 numpy 数组,每个元素的访问非常慢。使用向量运算:

$ python -mtimeit -s 'import numpy as np; a2=np.arange(10**6)' '
>    sum(1 for i in a2 if i % 1000 == 0)'
10 loops, best of 3: 1.53 sec per loop

$ python -mtimeit -s 'import numpy as np; a2=np.arange(10**6)' '
>    (a2 % 1000 == 0).sum()'
10 loops, best of 3: 22.6 msec per loop

$ python -mtimeit -s 'import numpy as np; a2=    range(10**6)' '
>    sum(1 for i in a2 if i % 1000 == 0)'
10 loops, best of 3: 90.9 msec per loop

【讨论】:

    【解决方案2】:

    在使用 sn-p 时,NumPy 在 Python 内置插件方面表现不佳,我并不感到惊讶。 NumPy 的大部分性能优势来自于避免循环,而是通过索引访问数组:

    在 NumPy 中,更常见的是执行以下操作:

    A = NP.random.randint(10, 100, 100).reshape(10, 10)
    w = A[A % 2 == 0]
    NP.save("test_file.npy", w)
    

    【讨论】:

    • +1 for A[A%2==0] 这是 OP 想要使用的行类型,当然除了 1000 而不是 2。
    【解决方案3】:

    a2 是一个 NumPy 数组,对吧?在 NumPy 中它可能需要这么长时间的一个可能原因(如果其他进程的活动没有像 Wayne Werner 建议的那样考虑它)是您正在使用 Python 循环遍历数组。在迭代的每一步,Python 都必须从 NumPy 数组中取出一个值并将其转换为 Python 整数,这并不是一个特别快的操作。

    当您能够将整个数组作为一个单元执行操作时,NumPy 的效果会更好。在您的情况下,一种选择(甚至可能不是最快的)是

    file.write("Multiple of 1000!\r\n" * (a2 % 1000 == 0).sum())
    

    尝试将其与纯 Python 等效项进行比较,

    file.write("Multiple of 1000!\r\n" * sum(filter(lambda i: i % 1000 == 0, a2)))
    

    file.write("Multiple of 1000!\r\n" * sum(1 for i in a2 if i % 1000 == 0))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      相关资源
      最近更新 更多