初始Numpy
一、什么是Numpy?
简单来说,Numpy 是 Python 的一个科学计算包,包含了多维数组以及多维数组的操作。
Numpy 的核心是 ndarray 对象,这个对象封装了同质数据类型的n维数组。起名 ndarray 的原因就是因为是 n-dimension-array 的简写。
二、ndarray 与 python 原生 array 有什么区别
- NumPy 数组在创建时有固定的大小,不同于Python列表(可以动态增长)。更改ndarray的大小将创建一个新的数组并删除原始数据。
- NumPy 数组中的元素都需要具有相同的数据类型,因此在存储器中将具有相同的大小。数组的元素如果也是数组(可以是 Python 的原生 array,也可以是 ndarray)的情况下,则构成了多维数组。
- NumPy 数组便于对大量数据进行高级数学和其他类型的操作。通常,这样的操作比使用Python的内置序列可能更有效和更少的代码执行。越来越多的科学和数学的基于Python的包使用NumPy数组,所以需要学会 Numpy 的使用。
三、Numpy 的矢量化(向量化)功能
如果想要将一个2-D数组 a 的每个元素与长度相同的另外一个数组 b 中相应位置的元素相乘,使用 Python 原生的数组实现如下:
for (i = 0; i < rows; i++): {
for (j = 0; j < columns; j++): {
c[i][j] = a[i][j]*b[i][j];
}}
使用 Numpy 实现的话,则可以直接使用矢量化功能:
c = a * b
矢量化代码有很多优点,其中包括:
-
矢量化代码更简洁易读
-
更少的代码行通常意味着更少的错误
-
该代码更接近地类似于标准数学符号(使得更容易,通常,以正确地编码数学构造)
-
矢量化导致更多的“Pythonic”代码。如果没有向量化,我们的代码将会效率很低,难以读取
for循环。
N维数组 ndarray
Numpy 中最重要的一个对象就是 ndarray。
ndarray 结构图
ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。
从ndarray对象提取的任何元素(通过切片)由一个数组标量类型的 Python 对象表示。 下图显示了ndarray,数据类型对象(dtype)和数组标量类型之间的关系。
一、构建ndarray
import numpy as np
#一维数组
a = np.array([0,1,2,3])
a
Out[39]: array([0, 1, 2, 3])
#二维数组
b = np.array([[0,1,2],[4,5,6]])
b
Out[40]:
array([[0, 1, 2],
[4, 5, 6]])
#创建一个0-9的数组
a = np.arange(10)
a
Out[41]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#创建一个1-6,步长为2的数组
b = np.arange(1,6,2)
b
Out[42]: array([1, 3, 5])
二、常用的数组
# 全一矩阵
np.ones((3,3))
Out[43]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
# 零矩阵
np.zeros((2,2))
Out[44]:
array([[0., 0.],
[0., 0.]])
# 单位矩阵
np.eye(3)
Out[45]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
# 对角矩阵
np.diag(np.array([1,2,3,4]))
Out[46]:
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])
三、生成等差数列
linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
- endpoint: 结束点如果现在为True,那么输入的第二个参数将会成为数列的最后一个元素,反之则不一定。
- restep: 而retstep会改变计算的输出,输出一个元组,而元组的两个元素分别是需要生成的数列和数列的步进差值。
# 默认生成50个元素的等差序列,需设定起始值和终止值
np.linspace(1,10)
Out[47]:
array([ 1. , 1.18367347, 1.36734694, 1.55102041, 1.73469388,
1.91836735, 2.10204082, 2.28571429, 2.46938776, 2.65306122,
2.83673469, 3.02040816, 3.20408163, 3.3877551 , 3.57142857,
3.75510204, 3.93877551, 4.12244898, 4.30612245, 4.48979592,
4.67346939, 4.85714286, 5.04081633, 5.2244898 , 5.40816327,
5.59183673, 5.7755102 , 5.95918367, 6.14285714, 6.32653061,
6.51020408, 6.69387755, 6.87755102, 7.06122449, 7.24489796,
7.42857143, 7.6122449 , 7.79591837, 7.97959184, 8.16326531,
8.34693878, 8.53061224, 8.71428571, 8.89795918, 9.08163265,
9.26530612, 9.44897959, 9.63265306, 9.81632653, 10. ])
# 生成指定个数的等差序列
np.linspace(1,10,10)
Out[48]: array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
四、生成等比数列
logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
- base:等比基数 默认为10
# 创建10个1-1的等比数列, 因为默认基数是10 np.logspace(0, 0, 10) Out[55]: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) # 创建10个1-2的10次方之间的等比数列, 改变等比基数 np.logspace(0, 9, 10, base=2) Out[59]: array([ 1., 2., 4., 8., 16., 32., 64., 128., 256., 512.]) # 创建10个1-2的10次方之间的等比数列, 改变等比基数 np.logspace(0, 9, 10, base=2, dtype=int) Out[60]: array([ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512])
五、生成meshgrid网格矩阵
meshgrid函数通常在数据的矢量化上使用,但是使用的方法我暂时还不是很明确。而meshgrid的作用适用于生成网格型数据,可以接受两个一维数组生成两个二维矩阵,对应两个数组中所有的(x,y)对。接下来通过简单的shell交互来演示一下这个功能的使用,并做一下小结。
meshgrid(*xi, **kwargs)
功能:从一个坐标向量中返回一个坐标矩阵
参数: x1,x2...,xn:数组,一维的数组代表网格的坐标。 indexing:{'xy','ij'},笛卡尔坐标'xy'或矩阵'ij'下标作为输出,默认的是笛卡尔坐标。 sparse:bool类型,如果为True,返回一个稀疏矩阵保存在内存中,默认是False。 copy:bool类型,如果是False,返回一个原始数组的视图保存在内存中,默认是True。如果,sparse和copy都为False,将有可能返回一个不连续的数组。而且,如果广播数组的元素超过一个,可以使用一个独立的内存。如果想要对这个数组进行写操作,请先拷贝这个数组。 返回值:x1,x2,....,xn:ndarray(numpy数组)