赞
踩
本文通过一下小实验来学习NumPy的相关知识。
PS:若需要更加详细的查阅NumPy所提供的接口,可以查阅 官方文档 。
提示:以下是本篇文章正文内容,下面案例可供参考
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。是在学习机器学习、深度学习之前应该掌握的一个非常基本且实用的Python库。
代码如下(示例):
import引入,as np 给numpy起个小名叫牛皮(np)
import numpy as np
NumPy为什么能够受到各个数据科学从业人员的青睐与追捧,其实很大程度上是因为NumPy在向量计算方面做了很多优化,接口也非常友好(总之就是用起来很爽)。而这些其实都是在围绕着NumPy的一个 核心数据结构ndarray 。
ndarray的全称是N-Dimension Arrary,字面意义上其实已经表明了一个ndarray对象就是一个N维数组。但要注意的是,ndarray是同质的。同质的意思就是说 N维数组里的所有元素必须是属于同一种数据类型的 。 (PS: python中的list是异质的) 。
ndarray对象实例化好了之后,包含了一些基本的属性。比如shape,ndim,size,dtype。其中:
1 shape:ndarray对象的形状,由一个tuple表示;
2 ndim:ndarray对象的维度;
3 size:ndarray对象中元素的数量;
4 dtype:ndarray对象中元素的数据类型,例如int64,float32等。
代码如下(示例):
# 导入numpy并取别名为np
import numpy as np
# 构造ndarray
a = np.arange(15).reshape(3, 5)
# 打印a的shape,ndim,size,dtype
print(a.shape)
print(a.ndim)
print(a.size)
print(a.dtype)
实例化ndarray对象的函数有很多种,但最为常用的函数是array,zeros,ones以及empty。
import numpy as np
# 使用列表作为初始值,实例化ndarray对象a
a = np.array([2,3,4])
# 打印ndarray对象a
print(a)
通常在写代码的时候,数组中元素的值一般都喜欢先初始化成0,如果使用array的方式实例化ndarray对象的话,虽然能实现功能,但显得很麻烦( 首先要有一个全是0的list )。那有没有简单粗暴的方式呢,有!!那就是zeros函数,你只需要把ndarray的shape作为参数传进去即可。
import numpy as np
# 实例化ndarray对象a,a是一个3行4列的矩阵,矩阵中元素全为0
a = np.zeros((3, 4))
# 打印ndarray对象a
print(a)
如果想把数组中的元素全部初始化成1,聪明的你应该能想到就是用ones函数,ones的用法与zeros一致。代码如下:
import numpy as np
# 实例化ndarray对象a,a是一个3行4列的矩阵,矩阵中元素全为1
a = np.ones((3, 4))
# 打印ndarray对象a
print(a)
如果不想要01,想要用随机值作为初始值来实例化ndarray对象,empty函数能够满足你。empty的使用方式与zeros和ones如出一辙,代码如下:
import numpy as np
# 实例化ndarray对象a,a是一个2行3列的矩阵,矩阵中元素全为随机值
a = np.empty((2, 3))
# 打印ndarray对象a
print(a)
大概有三种形式,代码如下:第一种是直接改变属性,有点不优雅(其实就是太粗暴了)第二三种其实是一样的,不过两者有面向对象和面向过程的区别而已。
import numpy as np
a = np.zeros((3, 4))
# 1直接修改shape属性
a.shape = [4, 3]
# 2调用a的成员函数reshape将3行4列改成4行3列
a = a.reshape((4, 3))
# 3调用reshape函数将a变形成4行3列
a = np.reshape(a, (4, 3))
tips:有时候,我如果不关心有每个维度上的长度是多少,比如现在有一个6行8列的ndarray,然后想把它变形成有2列的ndarray(行的数量我懒得去想),此时我们可以在行的维度上传个-1即可
import numpy as np
a = np.zeros((6, 8))
# 行的维度上填-1,会让numpy自己去推算出行的数量,很明显,行的数量应该是24
a = a.reshape((-1, 2))
如果想要对ndarray对象中的元素做elementwise(逐个元素地)的算术运算非常简单,加减乘除即可。
import numpy as np
a = np.array([0, 1, 2, 3])
# a中的所有元素都加2,结果为[2, 3, 4, 5]
b = a + 2
# a中的所有元素都减2,结果为[-2, -1, 0, 1]
c = a - 2
# a中的所有元素都乘以2,结果为[0, 2, 4, 6]
d = a * 2
# a中的所有元素都平方,结果为[0, 1, 4, 9]
e = a ** 2
# a中的所有元素都除以2,结果为[0, 0.5, 1, 1.5]
f = a / 2
# a中的所有元素都与2比,结果为[True, True, False, False]
g = a < 2
相同shape的矩阵A与矩阵B之间想要做elementwise运算也很简单,加减乘除即可。
import numpy as np
a = np.array([[0, 1], [2, 3]])
b = np.array([[1, 1], [3, 2]])
# a与b逐个元素相加,结果为[[1, 2], [5, 5]]
c = a + b
# a与b逐个元素相减,结果为[[-1, 0], [-1, 1]]
d = a - b
# a与b逐个元素相乘,结果为[[0, 1], [6, 6]]
e = a * b
# a的逐个元素除以b的逐个元素,结果为[[0., 1.], [0.66666667, 1.5]]
f = a / b
在这里发现,矩阵相乘*只能完成相应元素之间进行乘法,我们在线性代数里所学的矩阵的乘法跟这个有本质的区别。
import numpy as np
A = np.array([[1, 1], [0, 1]])
B = np.array([[2, 0], [3, 4]])
# @表示矩阵乘法,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(A @ B)
# 面向对象风格,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(A.dot(B))
# 面向过程风格,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(np.dot(A, B))
有的时候想要知道ndarray对象中元素的和是多少,最小值是多少,最小值在什么位置,最大值是多少,最大值在什么位置等信息。这个时候可能会想着写一个循环去遍历ndarray对象中的所有元素来进行统计。NumPy为了解放我们的双手,提供了sum,min,max,argmin,argmax等函数来实现简单的统计功能,代码如下:
import numpy as np
a = np.array([[-1, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 13]])
# 计算a中所有元素的和,结果为67
print(a.sum())
# 找出a中最大的元素,结果为13
print(a.max())
# 找出a中最小的元素,结果为-1
print(a.min())
# 找出a中最大元素在a中的位置,由于a中有12个元素,位置从0开始计,所以结果为11
print(a.argmax())
# 找出a中最小元素在a中位置,结果为0
print(a.argmin())
需要注意的是,使用argmax,argmin函数时,返回的位置通常不是我们想要的。对于我们来说,往往会统计某行某列的最值,这需要对数组的轴进行选择。
拿下图举个例子,比如说,我们实例化下面的表格,构成一个三行四列的矩阵,我们往往想知道某一列的最值,那么就要对轴进行选择。
import numpy as np
info = np.array([[3000, 4000, 20000], [2700, 5500, 25000], [2800, 3000, 15000]])
# 沿着0号轴统计,结果为[2700, 3000, 15000]
print(info.min(axis=0))
# 沿着0号轴统计,结果为[3000, 5500, 25000]
print(info.max(axis=0))
NumPy的random模块下提供了许多生成随机数的函数,如果对于随机数的概率分布没有什么要求,则通常可以使用random_sample、choice、randint等函数来实现生成随机数的功能。
random_sample用于生成区间为[0, 1]的随机数,需要填写的参数size表示生成的随机数的形状,比如size=[2, 3]那么则会生成一个2行3列的ndarray,并用随机值填充。
import numpy as np
print(np.random.random_sample(size=[2, 3]))
如果想模拟像掷骰子、扔硬币等这种随机值是离散值,而且知道范围的可以使用choice实现。choice的主要参数是a、size和replace。a是个一维数组,代表你想从a中随机挑选;size是随机数生成后的形状。假如模拟5次掷骰子,replace用来设置是否可以取相同元素,True表示可以取相同数字;False表示不可以取相同数字,默认是True,代码如下:
import numpy as np
'''
掷骰子时可能出现的点数为1, 2, 3, 4, 5, 6,所以a=[1,2,3,4,5,6]
模拟10掷骰子所以size=10
结果可能为 [1 4 2 3 6]
'''
print(np.random.choice(a=[1, 2, 3, 4, 5, 6], size=10,replace=False))
randint的功能和choice差不多,只不过randint只能生成整数,而choice生成的数与a有关,如果a中有浮点数,那么choice会有概率挑选到浮点数。
randint的参数有3个,分别为low,high和size。其中low表示随机数生成时能够生成的最小值,high表示随机数生成时能够生成的最大值减1。也就是说randint生成的随机数的区间为[low, high)。假如模拟5次掷骰子,代码如下:
import numpy as np
'''
掷骰子时可能出现的点数为1, 2, 3, 4, 5, 6,所以low=1,high=7
模拟5此掷骰子所以size=5
结果可能为 [6, 4, 3, 1, 3]
'''
print(np.random.randint(low=1, high=7, size=5)
如果对于产生的随机数的概率分布有特别要求,NumPy同样提供了从指定的概率分布中采样得到的随机值的接口。举个例子就是高斯分布。
高斯分布又称为正态分布,其分布图形如下:
import numpy as np
'''
根据高斯分布生成5个随机数
结果可能为:[1.2315868, 0.45479902, 0.24923969, 0.42976352, -0.68786445]
从结果可以看出0.4左右得值出现的次数比较高,1和-0.7左右的值出现的次数比较低。
'''
print(np.random.normal(size=5))
其中normal函数除了size参数外,还有两个比较重要的参数就是loc和scale,它们分别代表高斯分布的均值和方差。loc影响的分布中概率最高的点的位置,假设loc=2,那么分布中概率最高的点的位置就是2。下图体现了loc对分布的影响
计算机产生的随机数是由随机种子根据一定的计算方法计算出来的数值。所以只要计算方法固定,随机种子固定,那么产生的随机数就不会变!
如果想要让每次生成的随机数不变,那么就需要设置随机种子(随机种子其实就是一个0到2
32
−1的整数)。设置随机种子很长简单,调用seed函数并设置随机种子即可,代码如下:
import numpy as np
# 设置随机种子为233
np.random.seed(seed=233)
data = [1, 2, 3, 4]
# 随机从data中挑选数字,结果为4
print(np.random.choice(data))
# 随机从data中挑选数字,结果为4
print(np.random.choice(data))
import numpy as np # a中有4个元素,那么这些元素的索引分别为0,1,2,3 a = np.array([2, 15, 3, 7]) # 打印第1个元素 # 索引0表示的是a中的第1个元素 # 结果为2 print(a[1]) # b是个2行3列的二维数组 b = np.array([[1, 2, 3], [4, 5, 6]]) # 打印b中的第1行 # 总共就2行,所以行的索引分别为0,1 # 结果为[1, 2, 3] print(b[0]) # 打印b中的第2行第2列的元素 # 结果为5 print(b[1][1])
import numpy as np a = np.array([2, 15, 3, 7]) # 使用for循环将a中的元素取出来后打印 for element in a: print(element) # 根据索引遍历a中的元素并打印 for idx in range(len(a)): print(a[idx]) # b是个2行3列的二维数组 b = np.array([[1, 2, 3], [4, 5, 6]]) # 将b展成一维数组后遍历并打印 for element in b.flat: print(element) # 根据索引遍历b中的元素并打印 for i in range(len(b)): for j in range(len(b[0])): print(b[i][j])
切片也与列表十分类似。如下图,如果我想要图中紫色的部分,**注意索引是左闭右开。**想要的是0-2,索引就写成0:3或:3
import numpy as np
# a中有4个元素,那么这些元素的索引分别为0,1,2,3
a = np.array([2, 15, 3, 7])
'''
将索引从1开始到最后的所有元素切片出来并打印
结果为[15 3 7]
'''
print(a[1:])
'''
将从倒数第2个开始到最后的所有元素切片出来并打印
结果为[3 7]
'''
print(a[-2:])
例如:以上就是今天要讲的内容,本文仅仅简单介绍了numpy的使用,而numpy提供了大量能使我们快速便捷地处理数据的函数和方法,本文参考了很多文章,也都自己经过编程,程序应该是没问题的,有什么问题可以私信或者在评论区留言。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。