【问题标题】:What are the advantages of NumPy over regular Python lists?与常规 Python 列表相比,NumPy 有哪些优势?
【发布时间】:2010-11-02 21:35:26
【问题描述】:

NumPy 与常规 Python 列表相比有哪些优势?

我有大约 100 个金融市场系列,我将创建一个 100x100x100 = 100 万个单元格的立方体数组。我将对每个 x 与每个 y 和 z 进行回归(3 变量),以用标准误差填充数组。

我听说对于“大型矩阵”,出于性能和可扩展性的原因,我应该使用 NumPy 而不是 Python 列表。问题是,我知道 Python 列表,它们似乎对我有用。

如果我迁移到 NumPy 会有什么好处?

如果我有 1000 个系列(即立方体中有 10 亿个浮点单元)怎么办?

【问题讨论】:

    标签: python arrays list numpy numpy-ndarray


    【解决方案1】:

    NumPy 的数组比 Python 列表更紧凑——您描述的列表列表在 Python 中至少需要 20 MB 左右,而单元格中具有单精度浮点数的 NumPy 3D 数组将适合 4兆。使用 NumPy 读取和写入项目的访问速度也更快。

    也许你对一百万个单元不太在意,但你肯定会关心十亿个单元——这两种方法都不适合 32 位架构,但在 64 位构建中,NumPy 4 GB 左右,仅 Python 就需要至少约 12 GB(大量指针大小翻倍)——这是一个更昂贵的硬件!

    差异主要是由于“间接性”——Python 列表是指向 Python 对象的指针数组,每个指针至少 4 个字节加上即使是最小的 Python 对象也有 16 个字节(4 个用于类型指针,4 个用于引用count, 4 代表值——内存分配器四舍五入到 16)。 NumPy 数组是一个统一值数组——单精度数字每个占用 4 个字节,双精度数字占用 8 个字节。不太灵活,但您为标准 Python 列表的灵活性付出了巨大的代价!

    【讨论】:

    • 我一直在尝试使用“sys.getsizeof()”来比较具有相同元素数量的 Python 列表和 NumPy 数组的大小,它似乎并不表明 NumPy 数组小得多。是这种情况还是 sys.getsizeof() 无法确定 NumPy 数组的大小?
    • @JackSimpson getsizeof 不可靠。该文档明确指出:仅考虑直接归因于对象的内存消耗,而不考虑它所引用的对象的内存消耗。这意味着如果您嵌套了 python 列出元素的大小不考虑在内。
    • getsizeof on a list 仅告诉您列表对象本身消耗了多少 RAM 以及其数据数组中的指针消耗了多少 RAM,它不会告诉您列表对象消耗了多少 RAM这些指针所指的对象。
    • @AlexMartelli,你能告诉我你从哪里得到这些数字吗?
    • 请注意,您对列表列表的等效 Python 列表大小的估计是错误的。 C floats(4 字节)的 4 GB numpy 数组将转换为接近 32 GB 的 lists 和 Python floats(实际上是 C doubles),而不是 12 GB; 64 位 Python 上的每个 float 占用约 24 个字节(假设分配器中没有对齐损失),再加上 list 中的另外 8 个字节来保存引用(并且忽略了 lists 的过度分配和对象标头它们自己,这可能会增加另一个 GB,具体取决于发生的过度分配的确切程度)。
    【解决方案2】:

    NumPy 不仅效率更高;它也更方便。您可以免费获得大量向量和矩阵运算,这有时可以避免不必要的工作。而且它们也得到了有效实施。

    例如,您可以直接从文件中将多维数据集读取到数组中:

    x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))
    

    沿第二维求和:

    s = x.sum(axis=1)
    

    找出哪些单元格高于阈值:

    (x > 0.5).nonzero()
    

    沿第三维删除每个偶数索引切片:

    x[:, :, ::2]
    

    此外,许多有用的库都可以使用 NumPy 数组。例如,统计分析和可视化库。

    即使您没有性能问题,学习 NumPy 也是值得的。

    【讨论】:

    • 谢谢 - 您在第三个示例中提供了另一个很好的理由,事实上,我将在矩阵中搜索高于阈值的单元格。此外,我是从 sqlLite 加载的。文件方法会更有效率。
    【解决方案3】:

    Alex 提到了内存效率,Roberto 提到了便利性,这些都是好点。对于更多的想法,我会提到速度功能

    功能性:NumPy、FFT、卷积、快速搜索、基本统计、线性代数、直方图等内置了很多功能。真的,没有 FFT 谁能生存?

    速度:这是一个对列表和 NumPy 数组求和的测试,显示 NumPy 数组上的求和快 10 倍(在此测试中,里程可能会有所不同)。

    from numpy import arange
    from timeit import Timer
    
    Nelements = 10000
    Ntimeits = 10000
    
    x = arange(Nelements)
    y = range(Nelements)
    
    t_numpy = Timer("x.sum()", "from __main__ import x")
    t_list = Timer("sum(y)", "from __main__ import y")
    print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
    print("list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))
    

    在我的系统上(当我运行备份时)提供:

    numpy: 3.004e-05
    list:  5.363e-04
    

    【讨论】:

      【解决方案4】:

      这是来自scipy.org website 的常见问题解答中的一个很好的答案:

      与(嵌套)Python 列表相比,NumPy 数组有哪些优势?

      Python 的列表是高效的通用容器。他们支持 (相当)有效的插入、删除、追加和连接, Python 的列表推导使它们易于构造和 操纵。但是,它们有一定的局限性:它们不支持 “向量化”操作,如元素加法和乘法, 它们可以包含不同类型的对象这一事实意味着 Python 必须存储每个元素的类型信息,并且必须 在对每个元素进行操作时执行类型调度代码。这 也意味着很少有列表操作可以通过 高效的 C 循环——每次迭代都需要类型检查和其他 Python API 簿记。

      【讨论】:

        【解决方案5】:

        几乎所有的 numpy 数组和 python 列表之间的主要区别都已经突出显示,我将在这里简单介绍一下:

        1. Numpy 数组在创建时具有固定大小,这与 Python 列表(可以动态增长)不同。更改 ndarray 的大小将创建一个新数组并删除原始数组。

        2. Numpy 数组中的元素都必须具有相同的数据类型(我们也可以具有异构类型,但不允许进行数学运算),因此在内存中的大小相同

        3. Numpy 数组有助于对大量数据进行数学运算和其他类型的运算。通常,与使用 python 构建序列相比,此类操作的执行效率更高,代码更少

        【讨论】:

          【解决方案6】:
          • NumPy 不是另一种编程语言,而是 Python 扩展模块。它提供对同类数据数组的快速高效的操作。 Numpy 具有固定的创建大小。
          • 在 Python 中:列表是用方括号编写的。 这些列表可以是同质的或异质的
          • 使用 Numpy 数组胜过 Python 列表的主要优点:
            1. 它消耗的内存更少。
            2. 比 python 列表快。
            3. 使用方便。

          【讨论】:

            【解决方案7】:

            NumPy 用于数组概念,列表概念用于 python。 python列表是指针python对象的数组。 NumPy 数组是统一值的数组。

            【讨论】:

            • 我看不出这个含糊不清的答案比这里更多解释和详细的答案增加了什么......
            猜你喜欢
            • 2010-10-23
            • 2022-10-20
            • 2013-09-22
            • 2012-05-17
            • 1970-01-01
            • 2013-09-01
            • 2016-01-04
            相关资源
            最近更新 更多