官网地址

什么是 numpy

numpy 是 Python 的一个科学计算包。提供了多种array对象、衍生对象(masked arrays 和 matrices)、及其对其日常疾速操作,包含数学、逻辑、形态操作、分类、抉择、I/O、离散傅里叶(discrete Fourier transforms)、根本线性代数、根本数据操作、随机墨迹等。
numpy 包的外围是ndarray,他分装了n-维 array 对象(每个维度的数据类型统一),这使得各种操作都在编译好的代码中执行,从而进步了性能。

NumPyarray对象 与 Python 规范序列区别:

  • NumPy 对象在创立时有一个固定的大小,而 Python 的 list 没有。扭转 ndarray 的大小会删除原来对象,创立一个新的对象
  • NumPy所有数据类型是统一的,这样在内存中占用的大小才是统一的。例外:能够有对象数组(Python,包含 NumPy),容许不同大小元素的数组。
  • NumPy 对象更容易对于大量数据进行高级数学和其余类型操作。相较于 Python 内置序列,NumPy 操作执行效率更高,代码更少。
  • 越来越多的迷信和数学 Python 包会应用 NumPy 包,只管它们反对 Python 内置序列,但在操作之前都会转换成 NumPy 对象。换言之,要想无效的应用当初的迷信\数学 Python 包,只理解 Python 内置序列是不够的,咱们也要理解 NumPy 对象的应用。

科学计算的要害就是序列大小和速度。举个简略例子,在一个一维的序列中,每个元素要与另一个长度雷同的序列相应的元素做乘积,咱们能够迭代每个元素。

c = []for i in range(len(a)):    c.append(a[i]*b[i])

这个过程会输入正确答案,但如果列表 a 和 b 每个元素都是几百万,那咱们就会为 Python 低效的循环付出代价。c 语言能够更快的实现雷同工作(咱们假如不去做变量申明、初始化和内存调配):

for(i = 0; i < rows; i++):{    c[i] = a[i]*b[i]}

这解决了解释Python代码和操作Python对象所波及的所有开销,但就义了Python编码的益处。此外,随着数据维度减少,工作量也减少,如在 2 维数组中,c 语言编码为

for (i = 0; i < rows; i++): {  for (j = 0; j < columns; j++): {    c[i][j] = a[i][j]*b[i][j];  }}

而 NumPy 为这两张计划这个为咱们提供了最优解:当波及到 ndarray 时,一一元素操作是默认模式,而实际上是由 提前变异的C语言疾速执行。NumPy 代码运行速度与 C 语言靠近,同时基于 Python 代码也很简洁(比 Python 还简介简洁!)。最初一个例子阐明了 NumPy 的两个劣势:矢量化(vectorization)和播送(broadcasting)。
c = a*b

矢量化

矢量化意味着代码中没有肉眼可见的循环和索引,而他们其实产生了,只不过优化后“机密的进行着”——由预编译的 C 语言运行。
矢量化长处

  • 矢量化代码更简洁易读
  • 代码越少,bug 越少
  • 代码更相似于规范的数学符号(这样批改代码的数学构造会更容易)
  • 向量化会有更多“Pythonic”代码,没有矢量化,代码就会充斥着低效和难以读取的循环。

播送

播送是一个术语,用于形容操作的隐式一一元素的行为。通常说来,在 NumPy中,包含算数、逻辑、按位、函数等所有操作,以这种隐式一一元素的形式进行——即播送。此外,上述举例中,a 和 b 能够是形态雷同的多维数组、标量、数组,甚至能够是不同形态的两个数组(前提是较小的数组扩充成较大数组的形态)。更多信息请见 broadcasting。

NumPy 的 ndarray 全面反对面向对象。例如,ndarray是一个类,具备多种办法和对象。其中,许多办法都被NumPy最外层命名空间函数反映,容许程序员在他们喜爱的任何范式中编写代码。这种灵活性使得 NumPy 数组和 NumPyndarray 成为了Python 中多位数据交互的理论语言。

装置

装置 NumPy 惟一须要的条件就是 Python。如果你不懂 Python,只想用最简略的形式的话,咱们举荐anaconda,它包含了 Python、NumPy 和许多其余常见科学计算和数据分析的Python 包。
Linux 和 macOS 装置 NumPy 能够应用pipconda,或者应用下载源。更多信息请参考https://numpy.org/install/#py...。

  • donda
    你能够从defaults或者conda-forge 装置 numpy。
 Best practice, use an environment rather than install in the base envconda create -n my-envconda activate my-env# If you want to install from conda-forgeconda config --env --add channels conda-forge# The actual install commandconda install numpy
  • pip
    pip install numpy

NumPy 疾速启动

应用 NumPy 前须要先理解Python;须要装置matplotlib

学习指标

  • 理解一维、二维和 n 维数组的区别
  • 理解在不应用 for 循环的状况下如何将一些线性代数利用到 n 维数组中
  • 理解 n 维数组的轴和形态个性

[基础知识]

NumPy 的次要对象为平均的多维数组。数组是元素表(通产为数字),所有元素的类型统一,由一个非负整数的元组进行索引。在 NumPy 中,维度称为轴(axes)。
例如,在一个3 维空间中,一个点的坐标数组为[1, 2, 1],它只有一个轴,轴含有 3 个元素,因而咱们能够说其长度为 3。上面的例子中的数组中有 2 个轴,第一个轴的长度为 2,第二个长度为 3.

[[1., 0., 0.], [0., 1., 2.]]

NumPy 的数组类称为ndarray,别名为array。记住:numpy.array与 Python 规范库的类array.array不同,后者只能解决认为数组,且性能较少。

ndarray最重要的参数:

  1. ndarray.ndim :数组维度的数量
  2. ndarray.shape: 数组的维度,返回一个表明每个维度的数组的大小的元组,如一个 n 行 m 列的矩阵,其 shape 为(n,m),元组的长度就是ndim值。
  3. ndarray.size:数组所有元素的个数,等于 shape 所有值的乘积
  4. ndarray.dtype:数组中元素的数据类型,咱们能够创立或者指定为规范 Python 数据类型,也能够应用 NumPy 提供的类型,如numpy.int32、numpy.int16、numpy.float64等
  5. ndarray.itemsize:数组中每个元素的 字节大小,例如float64的大小为 8(64/8),float64为 4 字节。等同于ndarray.dtype.itemsize.
  6. ndarray.data:

创立数组

  • 将列表或者元组转换为数组
import numpy as npa = np.array([2, 3, 4])a #array([2, 3, 4])a.dtype #dtype('int64')b = np.array([1.2, 3.5, 5.1])b.dtype #dtype('float64')

有一种常见的谬误就是放入太多了参数,而要求是放入一个为序列的参数

a = np.array(1, 2, 3, 4)    # WRONGTraceback (most recent call last):  ...TypeError: array() takes from 1 to 2 positional arguments but 4 were givena = np.array([1, 2, 3, 4])  # RIGHT

array 办法 将含有一层序列的序列转换成二维数组,将含有两层序列的序列转换成三维数组,以此类推。

b = np.array([(1.5, 2, 3), (4, 5, 6)])barray([[1.5, 2. , 3. ],       [4. , 5. , 6. ]])b.shape #(2,3)

创立数组时能够指定数据类型

c = np.array([[1, 2], [3, 4]], dtype=complex)carray([[1.+0.j, 2.+0.j],       [3.+0.j, 4.+0.j]])
  • 通过原始占位符创立数组
    通常来说,数组元素的类型未知,但其大小始终。因而,NumPy 也能够通过原始占位符的办法创立数组,这种办法缩小了裁减数组这种高老本操作的的须要。
  • zero、ones、empty
    zero函数能够创立一个全是0 的数组,
    ones函数能够创立全是 1 的数组,
    empty函数能够依据缓存创立一个随机内容的数组。
    这三种办法数据类型默认为float64,但能够通过关键字参数dtype进行批改。
np.zeros((3, 4))array([[0., 0., 0., 0.],       [0., 0., 0., 0.],       [0., 0., 0., 0.]])np.ones((2, 3, 4), dtype=np.int16)array([[[1, 1, 1, 1],        [1, 1, 1, 1],        [1, 1, 1, 1]],       [[1, 1, 1, 1],        [1, 1, 1, 1],        [1, 1, 1, 1]]], dtype=int16)np.empty((2, 3))array([[3.73603959e-262, 6.02658058e-154, 6.55490914e-260],  # may vary       [5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
  • 创立数字序列
    arange函数能够创立一个相似与range的序列,但返回数组。
np.arange(10, 30, 5) #头、尾、步长array([10, 15, 20, 25])np.arange(0, 2, 0.3)  # it accepts float argumentsarray([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])
  • linspace
    当浮点数作为arange的参数时,因为精度问题,通常很难预测每个元素的值,因而最好应用linspace函数,这个函数能够接管元素个数作为一个参数。
from numpy import pinp.linspace(0, 2, 9)  array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  ])x = np.linspace(0, 2 * pi, 100)f = np.sin(x)
  • 其余

array|zeros|zeros_like|ones|ones_like|empty|empty_like
等等等等

打印数组

NumPy 数组构造形似嵌套列表,但具备一些特色

  • 最初的轴从左向右打印
  • 倒数第二从上到下打印
  • 其余从上到下打印,每个切片与下一个切片各一个空行
  • 如果矩阵太大的话,会主动跳过总监局部,只显示周围,若要全副显示,咱们能够设置set_printoptions
c = np.arange(24).reshape(2, 3, 4)  # 3d arrayprint(c)[[[ 0  1  2  3]  [ 4  5  6  7]  [ 8  9 10 11]] [[12 13 14 15]  [16 17 18 19]  [20 21 22 23]]]np.set_printoptions(threshold=sys.maxsize)  # sys module should be imported

基本操作

  1. 算术操作利用于元素身上,后果返回一个新的答案数组。
a = np.array([20, 30, 40, 50])b = np.arange(4)b #array([0, 1, 2, 3])c = a - bc #array([20, 29, 38, 47])b**2 #array([0, 1, 4, 9])10 * np.sin(a) #array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])a < 35array([ True,  True, False, False])
  1. *求乘积操作是针对于每个元素,如果要减小矩阵操作,应用@或者dot函数。
A = np.array([[1, 1],              [0, 1]])B = np.array([[2, 0],              [3, 4]])A * B     # elementwise productarray([[2, 0],       [0, 4]])A @ B     # matrix productarray([[5, 4],       [3, 4]])A.dot(B)  # another matrix productarray([[5, 4],       [3, 4]])
  1. +=*=操作是对元数组的操作,不会返回一个新的数组。

    rg = np.random.default_rng(1)  # create instance of default random number generatora = np.ones((2, 3), dtype=int)b = rg.random((2, 3))a *= 3aarray([[3, 3, 3],    [3, 3, 3]])b += abarray([[3.51182162, 3.9504637 , 3.14415961],    [3.94864945, 3.31183145, 3.42332645]])a += b  # b is not automatically converted to integer typeTraceback (most recent call last): ...numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
  2. 当操作的数组们的数据类型不同,数组后果与更加综合准确的统一(upcasting)

    a = np.ones(3, dtype=np.int32)b = np.linspace(0, pi, 3)b.dtype.name'float64'c = a + bcarray([1.        , 2.57079633, 4.14159265])c.dtype.name'float64'd = np.exp(c * 1j)darray([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,    -0.54030231-0.84147098j])d.dtype.name'complex128'
  3. 许多一元操作,如求所有元素的和,在ndarray类的办法中。

    a = rg.random((2, 3))aarray([[0.82770259, 0.40919914, 0.54959369],    [0.02755911, 0.75351311, 0.53814331]])a.sum()3.1057109529998157a.min()0.027559113243068367a.max()0.8277025938204418
  4. 在默认状况下,对数组的操作能够不论其形态,看做列表即可。但在非凡状况下,能够指定axis参数,沿着这个轴进行操作。

    b = np.arange(12).reshape(3, 4)barray([[ 0,  1,  2,  3],    [ 4,  5,  6,  7],    [ 8,  9, 10, 11]])>>>b.sum(axis=0)     # sum of each columnarray([12, 15, 18, 21])>>>b.min(axis=1)     # min of each rowarray([0, 4, 8])>>>b.cumsum(axis=1)  # cumulative sum along each rowarray([[ 0,  1,  3,  6],    [ 4,  9, 15, 22],    [ 8, 17, 27, 38]])