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

2024-11-29 08:42:00
admin
原创
136
摘要:问题描述:NumPy与常规 Python 列表相比有哪些优势?我有大约 100 个金融市场系列,我将创建一个 100x100x100 = 100 万个单元格的立方体数组。我将对每个 x 和每个 y 和 z 进行回归(3 变量),以用标准误差填充数组。我听说,出于性能和可扩展性的原因,对于“大型矩阵”,我应该使...

问题描述:

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

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

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

如果我转向 NumPy 会有什么好处?

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


解决方案 1:

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

也许您不太在意一百万个单元,但您肯定会在意十亿个单元——这两种方法都不适合 32 位架构,但使用 64 位版本 NumPy 可以使用 4 GB 左右,而 Python 本身则需要至少大约 12 GB(许多指针的大小会增加一倍)——这是一个昂贵的硬件!

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

解决方案 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 也是值得的。

解决方案 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 网站上常见问题解答的一个很好的答案:

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

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

解决方案 5:

几乎所有人都强调了 numpy 数组和 python 列表之间的所有主要区别,我将在这里简要介绍一下:

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

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

  3. Numpy 数组有助于对大量数据进行数学和其他类型的操作。通常,此类操作比使用 Python 内置序列执行起来更高效,代码也更少

解决方案 6:

Python 中的标准可变多元素容器是列表。由于 Python 的动态类型,我们甚至可以创建异构列表。为了允许这些灵活的类型,列表中的每个项目都必须包含其自己的类型信息、引用计数和其他信息。也就是说,每个项目都是一个完整的 Python 对象。在所有变量都属于同一类型的特殊情况下,这些信息中的大部分都是多余的;将数据存储在固定类型数组(NumPy 样式)中会更高效。固定类型 NumPy 样式数组缺乏这种灵活性,但在存储和操作数据方面效率更高。

解决方案 7:

虽然人们似乎同意Numpy 数组比 Python 数组具有更高的内存效率、功能性和便利性,但我敢质疑其更快的写入速度

在以下示例中,我将随机数写入预先初始化且大小不断增加的 Python 和 Numpy 数组中:

import numpy as np
import time as tm
import random
import matplotlib.pyplot as plt

array_sizes = [1000,5000,10000,50000,100000,500000,1000000,5000000]

time = []
time_np = []

for size in array_sizes:
    print('Array size:', size)
    
    # array initilization
    array = [None]*size
    array_np = np.array([None]*size)

    tic = tm.monotonic()
    for i in range(size):
        array[i] = random.random()
    toc = tm.monotonic()
    print('PY:',toc-tic)
    time.append(toc-tic)

    tic = tm.monotonic()
    for i in range(size):
        array_np[i] = random.random()
    toc = tm.monotonic()
    print('NP:',toc-tic)
    time_np.append(toc-tic)

为了绘图,添加以下代码:

x = array_sizes
plt.figure().add_subplot(1, 1, 1).set_xscale('log')
plt.plot(x,time, color='red', label='Python array', marker='o')
plt.plot(x,time_np, color='blue', label='Numpy array', marker='^')
plt.title('Writing random numbers
to 1D Python and Numpy array', fontweight='bold', fontsize='14')
plt.xlabel('array size')
plt.ylabel('writing time / s')
plt.legend()
plt.show()

这些时间测量表明,写入 Numpy 数组的时间增加了一倍多。

这是什么原因呢?

向预初始化的 Numpy 和 Python 数组写入时间

解决方案 8:

  • NumPy 不是另一种编程语言,而是 Python 扩展模块。它提供对同类数据数组的快速高效操作。Numpy 具有固定的创建大小。

  • 在 Python 中:列表用方括号书写。这些列表可以是同构的,也可以是异构的

  • 与 Python 列表相比,使用 Numpy 数组的主要优点如下:

    1. 它消耗更少的内存。

    2. 与 python List 相比速度更快。

    3. 使用方便。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1043  
  IPD(Integrated Product Development,集成产品开发)是一种系统化的产品开发方法论,旨在通过跨职能团队的协作,优化产品开发的效率和质量。IPD流程强调从市场需求出发,通过并行工程、跨部门协作和阶段性评审,确保产品从概念到上市的每个环节都高效且可控。随着敏捷开发方法的普及,越来越多的企业开始...
华为IPD流程   41  
  随着企业产品开发复杂度的提升以及市场需求的快速变化,传统的产品开发模式逐渐显现出局限性。集成产品开发(IPD)流程与敏捷开发(Agile Development)作为两种主流的开发方法论,分别从系统化管理和快速响应需求的角度为企业提供了解决方案。然而,单独使用其中一种方法往往无法完全满足企业在效率、质量和创新上的多重需...
华为IPD流程   35  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司成功的关键因素之一。它不仅帮助华为在技术上实现了快速创新,还通过市场导向确保了产品的商业成功。IPD流程通过整合技术与市场双驱动,实现了从需求定义到产品交付的全生命周期管理。这种模式不仅提高了产品的开发效率,还降低了市...
IPD流程中PDCP是什么意思   32  
  在研发领域,集成产品开发(IPD)流程已经成为企业提升创新效率和市场竞争力的重要手段。然而,资源分配的不合理往往是制约IPD流程效率的关键因素之一。无论是人力资源、财务资源还是技术资源,如何高效分配直接关系到项目的成功与否。优化资源分配不仅能够缩短产品开发周期,还能降低研发成本,提升产品的市场竞争力。因此,掌握资源分配...
IPD流程中CDCP   34  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用