【问题标题】:Python Numpy: Confusion - why iterate in numpy [duplicate]Python Numpy:混乱 - 为什么在 numpy 中迭代 [重复]
【发布时间】:2018-11-27 18:23:06
【问题描述】:

我用纯 Python 编程 2 年。

现在我正在学习 Numpy,我很困惑。

在教程中给出了 Numpy 比纯 python 更高效的示例。给定示例,但是当我尝试例如简单迭代时:

import numpy as np
import time
start = time.time()
list = range(1000000)
array = np.arange(1000000)

for element in list:
    pass
print('\n'+str((time.time() - start)*1000)+'\n')
start = time.time()
for element in np.nditer(array, order='F'):
    pass
print('\n'+str((time.time() - start)*1000)+'\n')

我得到了一个输出:

87.67843246459961

175.25482177734375

从上面可以看出,在 Numpy 上的迭代效率远低于纯 Python。

我的问题是:我不明白,也无法自己解释为什么要使用 Numpy,以及:什么时候使用它?

【问题讨论】:

  • 您错过了向量化问题时效率更高的部分。此外,永远不要迭代数组 - 最好先转换为列表。
  • 除了 kabanus 所说的,还值得指出的是,您真的不应该将变量命名为“list”和“array”。
  • 如果你迭代,你会发现 numpy 数组更慢。它们的优势在于矢量化。

标签: python performance numpy


【解决方案1】:

Numpy 使用向量运算要快得多。 如果您将代码更改为:

array+=1

代替:

for element in np.nditer(array, order='F'):
    pass

你可以看到 numpy 大大优于常规的 python 代码

【讨论】:

    【解决方案2】:

    numpy 的优势在于您不需要迭代。 迭代没有问题,实际上在某些情况下可能有用,但是使用函数可以解决绝大多数问题是numpy。

    使用您的示例(使用 ipython 中的 %timeit 命令),如果您执行简单的操作,例如为列表的每个元素添加一个数字,那么直接使用 numpy 而不进行迭代显然要快得多。

    import numpy as np
    import time
    start = time.time()
    dlist = range(1000000)
    darray = np.arange(1000000)
    
    # Pure python
    %timeit [e + 2 for e in dlist]
    59.8 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    # Iterating numpy
    %timeit [e + 2 for e in darray]
    193 ms ± 8.61 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    # Converting numpy to list before iterating
    %timeit [e+2 for e in list(darray)]
    198 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    # Numpy
    %timeit darray + 2
    847 µs ± 8.81 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    对于更复杂的操作也是如此,比如求均值:

    %timeit sum(dlist)/len(dlist)
    16.5 ms ± 174 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    %timeit sum(darray)/len(darray)
    66.6 ms ± 583 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    # Converting to list then iterating
    %timeit sum(list(darray))/len(darray) 
    83.1 ms ± 541 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    # Using numpy's methods
    %timeit darray.mean()
    1.26 ms ± 5.34 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    一旦你了解了如何使用 Numpy,它的速度就会快得多。它需要一种完全不同的方式来查看数据,并熟悉它提供的功能,但是一旦你这样做了,就会产生更简单、更快的代码。

    【讨论】:

    • numpy 对字符串数据还是只对数字更快?
    • 还有一件事:当我将python列表转换为排列时,它总是比纯Python花费更多的时间。示例:我从搁置文件中获取数据并希望将它们转换为 numpy,因此转换将花费太多时间。
    • 一般来说,numpy 处理字符串数据的速度并不是非常快,尽管它可以处理它。您必须平衡以 numpy 可以使用的格式获取数据的设置成本与您将对其进行的计算数量。有一些选项可以将数据从磁盘直接加载到 numpy 数组中,效果很好。但是,与往常一样,请查看您的特定问题并找到最有效的方法。
    • 最后一个问题:我这几天也在学pandas:你觉得无论如何numpy能比pandas更好吗?
    • 我会说在大多数情况下它会更好。 pandas 建立在 numpy 之上,仅在您想要处理表格或索引数据时处理一组非常具体的问题。即便如此,在许多情况下,直接使用 numpy 仍然更简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2018-04-13
    • 2015-12-11
    相关资源
    最近更新 更多