什么是Numpy
NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等
NumPy包的核心是 ndarray 对象。它封装了python原生的同数据类型的 n 维数组,为了保证其性能优良,其中有许多操作都是代码在本地进行编译后执行的。
Numpy数组 和 原生Python List 对比:
- NumPy 数组在创建时具有固定的大小,与Python的原生数组对象(可以动态增长)不同。更改ndarray的大小将创建一个新数组并删除原来的数组。
- NumPy 数组中的元素都需要具有相同的数据类型,因此在内存中的大小相同。 例外情况:Python的原生数组里包含了NumPy的对象的时候,这种情况下就允许不同大小元素的数组。
- NumPy 数组有助于对大量数据进行高级数学和其他类型的操作。通常,这些操作的执行效率更高,比使用Python原生数组的代码更少。
为什么 NumPy 这么快
- 矢量化描述了代码中没有任何显式的循环,索引等 - 这些当然是预编译的C代码中“幕后”优化的结果。矢量化代码有许多优点,其中包括:
- 矢量化代码更简洁,更易于阅读
- 更少的代码行通常意味着更少的错误
- 代码更接近于标准的数学符号(通常,更容易正确编码数学结构)
- 矢量化导致产生更多 “Pythonic” 代码。如果没有矢量化,我们的代码就会被低效且难以阅读的for循环所困扰
Numpy数组 和 原生Python list内存存储数据的方式
从图中我们可以看出ndarray在存储数据的时候,数据与数据的地址都是连续的,这样就使得批量操作数组元素时速度更快。因为ndarray中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python原生list就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面Numpy的ndarray不及Python原生list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python原生list简单的多
# 对比numpy与python原生list运算速度
import random
import time
import numpy as np
a = []
for i in range(100000000):
a.append(random.random())
%time sum1=sum(a)
b=np.array(a)
%time sum2=np.sum(b)
结果
Wall time: 4.23 s
Wall time: 630 ms