Numpy基础语法

Numpy基础语法

Numpy是一个优秀的python第三方库,是Python生态系统中高性能科学计算和数据分析所需的基础软件包。它是几乎所有高级工具(如Pandas和scikit-learn)的基础。TensorFlow,PyTorch等大量机器学习框架的基础构建模块。

  1. NumPy 应用
  • NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。
  • SciPy 是一个开源的 Python 算法库和数学工具包。
  • SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
  • Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。它为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API)。
  • #个人理解Matplotlib即matrix-plot-library
  1. 使用Numpy
  • 由于Numpy不是内部库,首先需要引入
>>> import numpy as np
  1. NumPy Ndarray 对象
  • NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

  • Ndarry是NumPy中一种N维数组对象

特点:
1. 它是以个N维数组,(1<=N)
2. 它被用来存放同类型的数据。
#所以说,它并不等同于元组(python无数组)
3. ndarray 中的每个元素在内存中都有相同存储大小的区域。
4. ndarray内部存在指向数据的指针。
#具有C语言的特色
5. 数据类型或 dtype(data-type),即数组元素的数据类型。

  1. 创建一个ndarray对象:
  • 创建一个最简单的ndarray对象:
>>> import numpy as np
>>> a = np.array([1,2,3])
>>> a
array([1, 2, 3])
>>> print(a)
[1 2 3]

等价创建方法:

>>> b = (1,2,3)			
>>> a = np.array(b)	
>>> a
array([1, 2, 3])

**#b可以是一个列表;元组。甚至dict:**
>>> b = {"ss":123}
>>> a = np.array(b)
>>> a
array({'ss': 123}, dtype=object)
  • 生成矩阵(二维数组):
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])

#同样的方法我们还可以生成张量(多维数组)

  • 我们可以在生成ndarray的时候设置一些属性:
    numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
    Ndmin  指定生成数组的最小维度
    Dtype  数组元素的数据类型,可选
示例代码:
>>> a = np.array([1,  2,  3], dtype = complex)
>>> print (a)
[1.+0.j 2.+0.j 3.+0.j]	
  1. 数组的属性
  • 数组元素的数量:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.size
9
#数值上应该等于 rows * columns
  • 数组的形状:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.shape
(3, 3)		# rows * columns
  • 数组维度的数量:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.ndim
2
#没错,矩阵就是二维数组,不要犯糊涂
  • 数组元素类型:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')		
#int32是一种常见的数字类型,侧面证明array中元素的数据类型相同
  • 数组每个元素的大小,以字节为单位:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.itemsize
4
#这就类似C语言中的sizeof()
  1. NumPy 数据类型
  • NumPy支持的数据类型:
    很多。。。
    常见的有:bool;int16/32/64;unit16/32/64(无符号数);float32/64;complex64/128

  • 数据类型对象 (dtype)
    数据类型对象用来描述与数组对应的内存区域如何使用。

从以下几个方面入手:

  1. 数据的类型(整数,浮点数或者 Python 对象)
#比如在将字典转化成ndarray时dtype=object
>>> b = {"ss":123}
>>> a = np.array(b)
>>> a
array({'ss': 123}, dtype=object)

#数据类型是可以转化的
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
>>> a.dtype = 'float32'
>>> a
array([[1.4e-45, 2.8e-45, 4.2e-45],
       [5.6e-45, 7.0e-45, 8.4e-45],
       [9.8e-45, 1.1e-44, 1.3e-44]], dtype=float32)
       
#同时又不能随意的转化
>>> a = np.array(b)
>>> a
array({'ss': 123}, dtype=object)
>>> a.dtype
dtype('O')				#数据类型时Object
>>> a.dtype = 'int32'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python36\lib\site-packages\numpy\core\_internal.py", line 494, in _view_is_safe
    raise TypeError("Cannot change data-type for object array.")
TypeError: Cannot change data-type for object array.

  1. 数据的大小(例如, 整数使用多少个字节存储)
#数据的大小同样可变,但是可能会得到不可测的结果
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
>>> a.dtype = 'int16'
>>> a
array([[1, 0, 2, 0, 3, 0],
       [4, 0, 5, 0, 6, 0],
       [7, 0, 8, 0, 9, 0]], dtype=int16)

#数据类型同样不能随便变化,比如不能让他凭空的将精度变高

>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
>>> a.dtype = 'int64'
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.

  1. 数据的字节顺序(小端法或大端法)
    字节顺序是通过对数据类型预先设定"<“或”>“来决定的。”<“意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。”>"意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
  2. 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
    #类似C语言中的结构体。
  3. 如果数据类型是子数组,它的形状和数据类型
在这里插入代码片
  1. 快速创建矩阵的函数:
  • ones():
//创建向量
>>> np.ones(5)
array([1., 1., 1., 1., 1.])
//创建矩阵
>>> a = np.ones([3,3])
>>> a
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
//做一些改动
>>> a =3*np.ones([3,3])
>>> a
array([[3., 3., 3.],
       [3., 3., 3.],
       [3., 3., 3.]])
  • zeros():
//创建向量
>>> np.zeros(5)
array([0., 0., 0., 0., 0.])
//创建矩阵
>>> a = np.zeros([3,3])
>>> a
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
 //再次操作
>>> a =3* np.zeros([3,3])
>>> a
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
  1. NumPy创建随机数组----均态分布
  • np.random.rand(x,y)
    创建指定形状为 x*y 的矩阵
//默认生成的随机数的范围是0~1
>>> np.random.rand(3,3)
array([[3.29636146e-02, 4.90232936e-01, 3.40464701e-01],
       [3.94844706e-01, 4.80900614e-02, 2.06383792e-04],
       [9.43723782e-01, 8.83631432e-01, 2.90263091e-01]])
//做一些改动,改变随机数的范围.使之范围在1~10
>>> np.random.rand(3,3)*10
array([[4.76591306, 3.44215456, 5.66092258],
       [3.58430809, 9.85651945, 9.12340062],
       [2.47789989, 2.69133064, 4.49325786]])
  • np.random.uniform(x,y)
    生成范围在x~y的一个随机小数
>>> np.random.uniform(10,20)
13.740520696927998
  • np.random.randint(x,y)
    生成范围在x~y的一个随机整数
>>> np.random.randint(10,20)
15
  1. NumPy 从已有的数组创建数组
  • 使用 np.array() 和 np.asarray() 的区别
//上代码
>>> b = (1,2,3)

// array方法
>>> c=np.array(b)
>>> c
array([1, 2, 3])

// asarray方法
>>> d = np.asarray(b)
>>> d
array([1, 2, 3])

从上面代码看不出什么区别,这也就体现了他们共同的功能:array和asarray都可将结构数据转换为ndarray类型。

//上代码
>>> type(b)
<class 'tuple'>
>>> type(c)
<class 'numpy.ndarray'>
>>> type(d)
<class 'numpy.ndarray'>

它们真正的区别在于但是主要区别就是当数据源是ndarray时,
array仍会copy出一个副本,占用新的内存,但asarray不会。

//上代码
>>> a = (1,2,3)
>>> b = np.array(a)
>>> c = np.array(b)
//array实现copy功能
>>> c[0] = 3
>>> c
array([3, 2, 3])
>>> b
array([1, 2, 3])

//同样的操作对ndarray来一遍
>>> a = (1,2,3)
>>> b = np.asarray(a)
>>> c = np.asarray(b)
//asarray同样能够实现copy功能
>>> b[0]=3
>>> b
array([3, 2, 3])
>>> c
array([3, 2, 3])
  1. NumPy创建随机数组----正态分布
  • 给定均值/标准差/维度的正态分布np.random.normal(a,b,(x,y))
>>> np.random.normal(10,4,(3,3))
array([[12.34628758,  6.50655525,  5.56074923],
       [20.07590444,  2.31052866, 10.51850977],
       [ 2.27598256,  7.61946729,  6.61567373]])
//标准差就是方差再开根号。。
  1. NumPy 从数值范围创建数组
  • np.arange(x,y,x)
    x:起始值 y:终止值 z:步长
>>> np.arange(10,20,2)
array([10, 12, 14, 16, 18])

//可以看出ndarray类型像python列表,事实上它也确实可以像列表一样索引
  • np.linspace(x,y,z)
    以x为起始值,y为结束值,分隔z份,创建一维等差数组
//如果不给出第三个参数,那么默认是50
>>> np.linspace(1,10)
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)
array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])

//也可以皮一下
>>> np.linspace(1,1,10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

//对于这里面的 1. , 2. ,3. 不要太纠结,他们实际上就是1.0,2.0,3.0 
//上代码
>>> a = (1.,2.,3.)
>>> a
(1.0, 2.0, 3.0)
  • np.logspace(x,y,z)
    x为起始值,y为结束值,创建包含z个元素的一个一维等比数列
//同样的默认生成50个元素
>>> np.logspace(1,2)
array([ 10.        ,  10.48113134,  10.98541142,  11.51395399,
        12.06792641,  12.64855217,  13.25711366,  13.89495494,
        14.56348478,  15.26417967,  15.9985872 ,  16.76832937,
        17.57510625,  18.42069969,  19.30697729,  20.23589648,
        21.20950888,  22.22996483,  23.29951811,  24.42053095,
        25.59547923,  26.82695795,  28.11768698,  29.47051703,
        30.88843596,  32.37457543,  33.93221772,  35.56480306,
        37.2759372 ,  39.06939937,  40.94915062,  42.9193426 ,
        44.98432669,  47.14866363,  49.41713361,  51.79474679,
        54.28675439,  56.89866029,  59.63623317,  62.50551925,
        65.51285569,  68.6648845 ,  71.9685673 ,  75.43120063,
        79.06043211,  82.86427729,  86.85113738,  91.0298178 ,
        95.40954763, 100.        ])

//生成10个
>>> np.logspace(1,2,10) **或者** np.logspace(1,2,num = 10)
array([ 10.        ,  12.91549665,  16.68100537,  21.5443469 ,
        27.82559402,  35.93813664,  46.41588834,  59.94842503,
        77.42636827, 100.        ])

//以2为底数
>>> np.logspace(1,2,10,base=2)
array([2.        , 2.16011948, 2.33305808, 2.5198421 , 2.72158   ,
       2.93946898, 3.1748021 , 3.42897593, 3.70349885, 4.        ])

  1. NumPy 切片和索引
  • ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,但是列表生成式是更好的方法。

  • 对向量使用切片和索引

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = slice(2,9,2)
>>> b
slice(2, 9, 2)
>>> a[b]
array([2, 4, 6, 8])		//b只是切片本身,只有和ndarray结合起来才具有意义

//我们还可以使用**列表生成式**的方式生成切片
>>> c = a[2,9,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array
>>> c = a[2:9:2]
>>> c
array([2, 4, 6, 8])

//冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。
如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 
[2:7],那么则提取两个索引(不包括停止索引)之间的项。
//	a[2:9:2] == a[slice(2,9,2)]  不恰当的说:**[2:9:2] == slice(2,8,2)**
//所以说直接用列表生成式的方法比较好
  • 多维数组的切片和索引
>>> a = np.random.normal(10,4,(4,5))
>>> a
array([[ 3.05513778, 10.70987312,  5.67037114,  8.08392751,  5.92022034],
       [11.99962594,  8.60524009,  9.87238926, 13.02399218,  9.11991441],
       [16.45312757, 10.63062961,  6.71416586, 18.65010408, 10.90224202],
       [17.77987518,  9.43236602,  8.63643317,  8.31419578, 11.0124451 ]])
>>> b = a[1:3, 2:4]		//**截取2~3行,3~4列的数据(索引从0开始)**
>>> b
array([[ 9.87238926, 13.02399218],
       [ 6.71416586, 18.65010408]])

//实际上,多维数组的操作可以简化成这样 **a[操作1,操作2,操作3,···]**
操作1是针对第一秩(行)的操作;操作2 是针对第二秩(列)的操作;并以此类推····
可见逗号是分割对不同维度操作的间隔符

//上代码
>>> a = np.random.rand(3,4)
>>> a
array([[0.64359865, 0.78614581, 0.60116405, 0.49593726],
       [0.74587207, 0.02149204, 0.66179379, 0.11995186],
       [0.80315084, 0.36740358, 0.36714436, 0.77535863]])
       
>>> a[0,]		//取第一行的元素
array([0.64359865, 0.78614581, 0.60116405, 0.49593726])
>>> a[0,...]	//取第一行的元素
array([0.64359865, 0.78614581, 0.60116405, 0.49593726])

>>> a[,0]
  File "<stdin>", line 1
    a[,0]
      ^
SyntaxError: invalid syntax
//此处报错了,所以说...还是很有必要的

>>> a[...,0]	//取第一列的元素
array([0.64359865, 0.74587207, 0.80315084])
>>> a[...,0:]	//取第一列及其之后所有列的元素
array([[0.64359865, 0.78614581, 0.60116405, 0.49593726],
       [0.74587207, 0.02149204, 0.66179379, 0.11995186],
       [0.80315084, 0.36740358, 0.36714436, 0.77535863]])
>>> a[...,3:]
array([[0.49593726],
       [0.11995186],
       [0.77535863]])
  • 整数数组索引
//以下实例获取数组中(0,0),(1,1)和(2,0)位置处的元素
>>> x = np.array([[1,  2],  [3,  4],  [5,  6]])
>>> y = x[[0,1,2],  [0,1,0]]
>>> y
array([1, 4, 5])
  • 布尔索引
//布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。可以看作
是一个**过滤器**
//上代码
>>> a
array([[0.64359865, 0.78614581, 0.60116405, 0.49593726],
       [0.74587207, 0.02149204, 0.66179379, 0.11995186],
       [0.80315084, 0.36740358, 0.36714436, 0.77535863]])
>>> a[a>0.5]
array([0.64359865, 0.78614581, 0.60116405, 0.74587207, 0.66179379,
       0.80315084, 0.77535863])
//最终得到得到的结果是一个向量

//下列代码可以从数组中过滤掉非复数元素。
>>> a = np.array([1,  2+6j,  5,  3.5+5j])
>>> a[np.iscomplex(a)]
array([2. +6.j, 3.5+5.j])
  1. NumPy 变形
  • reshape()
>>> np.ones(12)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> a = np.ones(12)
>>> a.reshape(3,4)
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

//综合使用
>>> a = np.ones(12).reshape(3,4)
>>> a
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
  1. NumPy 广播(Broadcast)
  • 广播的规则:

    • 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
    • 输出数组的形状是输入数组形状的各个维度上的最大值。
    • 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
    • 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
  1. NumPy 迭代数组
  • NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。

迭代器最基本的任务的可以完成对数组元素的访问。

//上代码
>>> a = np.arange(6).reshape(2,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> for i in np.nditer(a):
... print(i+',')
  File "<stdin>", line 2
    print(i+',')
        ^
IndentationError: expected an indented block
//在命令行模式下回车不自动缩进!

>>> for i in np.nditer(a):
...     print (i+',' )
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
numpy.core._exceptions.UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U11'), dtype('<U11')) -> dtype('<U11')
//此处的**i**已经不是普通的字符型了,不能够简单的与字符进行拼接

>>> for i in np.nditer(a):
...     print(i,end=',')
...
0,1,2,3,4,5,>>>
>>>
  • 控制遍历的顺序
//上代码
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> for i in np.nditer(a,order = 'C'):		//很显然这是按照行序进行迭代
...     print(i,end=',')
...
0,1,2,3,4,5,>>>
>>> for i in np.nditer(a,order = 'F'):		//这是按照列序进行迭代
...     print(i,end=',')
...
0,3,1,4,2,5,>>>
>>>
  • 向量的转置
//上代码
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> a.T
array([[0, 3],
       [1, 4],
       [2, 5]])
       
>>> for i in np.nditer(a):
...     print(i,end=',')
...
0,1,2,3,4,5,>>>
>>> for i in np.nditer(a.T):
...     print(i,end=',')
...
0,1,2,3,4,5,>>>
//我们发现,矩阵转置之后再进行迭代顺序并没有发生改变,事实上,在内存中它们的存储顺序的确一样,选择
的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是**行序优先**(row-major order,或
者说是 C-order)。

>>> for i in np.nditer(a,order = 'F'):
...     print(i,end=',')
...
0,3,1,4,2,5,>>>     
//按照列进行迭代就使得迭代的方式发生了改变

  1. Numpy 数组操作
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值