python高级--数据分析(NumPy)
NumPy 库
文档地址 : NumPy参考
import numpy as np
一、创建ndarray(多维数组)
1. 使用np.array()创建多维数组
#传入一个列表即可创建一个多维数组
#注意: 内部内容的数据类型是相同的
>>> np.array([1,2,3,4])
array([1, 2, 3, 4])
>>> np.array([1,2,3.0,4]) #如果有浮点数就都变成浮点数了
array([1., 2., 3., 4.])
>>> np.array([1,2,3.0,'4']) #如果有字符串就都变成字符串了
array(['1', '2', '3.0', '4'], dtype='<U32')
优先级: str > float > int
2.使用np的常用函数(routines)创建
指定数值创建数组
1) np.ones(shape,dtype=None)
功能: 按照指定形状创建多维数组,并用1填充
"""
shape:用于指定创建的多维数组的形状,可传入2 或者(2, 3) #有几个数字就是几维数组
dtype:数据的类型[np.int8, np.float64]
返回值:返回创建好的多维数组
创建的数组用 1 来填充
"""
>>> np.ones(shape=(2,3), dtype=np.int) #二维数组,数据类型为整形
array([[1, 1, 1],
[1, 1, 1]])
>>> np.ones(shape=(2,3,5)) #三维数组,数据类型默认为浮点类型
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., 1.],
[1., 1., 1., 1., 1.]]])
2) np.zeros(shape,dtype=None)
功能: 按照指定形状创建多维数组,并用0填充
"""
shape:用于指定形状,可传入2 或者(2, 3) #有几个数字就是几维数组
dtype:数据的类型[np.int8, np.float64]
返回值:返回创建好的多维数组
创建的数组用 0 来填充
"""
>>> np.zeros(shape=(2,3), dtype=np.int)
array([[0, 0, 0],
[0, 0, 0]])
>>> np.zeros(shape=(2,3,5)) #三维数组,数据类型默认为浮点类型
array([[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]])
3) np.full(shape,fill_value,dtype=None)
功能:创建一个被fill_value填充的形状为shape的数组
"""
shape:用于指定形状,可传入2 或者(2, 3) #有几个数字就是几维数组
fill_value:填充数组的数字(整数/小数)
dtype:数据的类型[np.int8, np.float64]
返回值:返回创建好的多维数组
"""
>>> np.full(shape=(5,3),fill_value=9,dtype=float)
array([[9., 9., 9.],
[9., 9., 9.],
[9., 9., 9.],
[9., 9., 9.],
[9., 9., 9.]])
>>> np.full(shape=(5),fill_value=9,dtype=float)
array([9., 9., 9., 9., 9.])
4) np.eye(N,dtype=None)
功能:创建一个N行N列的的方阵,主对角线为
1,其他位置为0
'''
N : 指定矩阵有多少行/列
dtype:数据的类型[np.int8, np.float64]
'''
>>> np.eye(N=(3))
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
二、指定数值创建(一维)数组
1) np.arange([start,] stop[, step,], dtype=None)
功能 : 在一个范围内,每隔step取一个值
范围 :[start,stop)
'''
start:起始值 (默认为0)
stop:终止指 (必传,取值取到终止值之前)
step:步长 (每隔多少取一个值。默认为1)
dtype:数据的类型[np.int8, np.float64]
返回值:返回一个一维数组
'''
>>> np.arange(1,10)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(1,10,2)
array([1, 3, 5, 7, 9])
>>> np.arange(1,10,3)
array([1, 4, 7])
2) np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
功能 : 把start到stop这个范围内的数,等分成num份,填入数组
'''
start:起始值 (必传)
stop: 终止指 (必传)
num:份数 (平均分多少份。默认为50)
dtype:数据的类型[np.int8, np.float64]
返回值:返回一个一维数组
'''
>>> np.linspace(1,10,3)
array([ 1. , 5.5, 10. ])
>>> np.linspace(1,10,4)
array([ 1., 4., 7., 10.])
>>> np.linspace(1,10,5)
array([ 1. , 3.25, 5.5 , 7.75, 10. ])
3) np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
功能 : 把start到stop这个范围内的数,等分成num份,获得的指作为base的指数,列出来
'''
start:起始值 (必传)
stop: 终止指 (必传)
num:份数 (平均分多少份。默认为50)
base:底数(等分的数为指数,base为底数,默认为10)
dtype:数据的类型[np.int8, np.float64]
返回值:返回一个一维数组
'''
>>> np.logspace(1,3,3)
array([ 10., 100., 1000.])
>>> np.logspace(1,3,3,base=2)
array([2., 4., 8.])
三、随机创建简单多维数组
1) np.randint(low, high=None, size=None, dtype=’l’)
功能:从low到high的范围随机取整数,来填充多维数组
范围:[low,high)
'''
low : 起始值
high : 终止值
size : 形状,可传入2 或者(2, 3) #有几个数字就是几维数组
'''
>>> np.random.randint(1,5,5)
array([1, 1, 4, 4, 2])
>>> np.random.randint(1,5,size=(2,3))
array([[3, 4, 2],
[4, 2, 3]])
2) randn(d0, d1, …, dn)
功能:产生以0为中心,方差为1的标准正态分布的随机数来填充的数组
'''
d0,d1,...dn :有多少维度就传入多少参数,每个参数用来指定其维度中的个数
'''
>>> np.random.randn(1)
array([-0.63000927])
>>> np.random.randn(1,2) #产生一个二维数组,数组中有一个数组,一个数组中有两个数组
array([[1.7337034 , 0.26984471]])
>>> np.random.randn(3,1,2) #产生一个三维数组,三个数组中有一个数组,一个数组中有两个数组
array([[[-0.24282433, 0.58477987]],
[[ 1.20179445, -0.37844403]],
[[-1.21172519, -0.44742786]]])
3) np.random.random(size=None)
功能 : 随机生成0到1的随机数(0,1)填充数组
'''
size : 形状,可传入2 或者(2, 3) #有几个数字就是几维数组
'''
>>> np.random.random(size=(2))
array([0.58240105, 0.08470789])
>>> np.random.random(size=(2,3))
array([[0.58753102, 0.42687467, 0.42224585],
[0.47899402, 0.97172723, 0.68236609]])
>>> np.random.random(size=(2,3,4))
array([[[0.26987054, 0.67503316, 0.69864426, 0.05138955],
[0.31779865, 0.77244082, 0.13928269, 0.84568712],
[0.02697585, 0.75558307, 0.61794721, 0.8085395 ]],
[[0.0434348 , 0.77116443, 0.26713491, 0.73698106],
[0.55828175, 0.3051471 , 0.93931506, 0.37395939],
[0.12744913, 0.61601584, 0.8920521 , 0.60167184]]])
4)np.random.normal(loc=0.0, scale=1.0, size=None)
功能 : 创建指定中心和方差的标准正态分布的多维数组
'''
loc: 正态分布的中心(默认为0.0)
scale:方差,正态分布的变化范围(默认为1.0)
size:形状,可传入2 或者(2, 3) #有几个数字就是几维数组
返回值: 一个多维数组
'''
>>> np.random.normal(loc=5,scale=1,size=(2,3))
array([[4.07465472, 5.35638428, 5.51140931],
[8.47282828, 5.87924045, 4.07243969]])
>>> np.random.normal(loc=5,scale=1,size=(2,3,2))
array([[[6.01947885, 4.14599795],
[4.90589513, 6.26964203],
[3.28105784, 5.54700347]],
[[3.86962801, 6.43496295],
[4.76825202, 4.80721522],
[5.00938992, 4.66371381]]])
四、多维数组(ndarray)的属性
1、维度(ndim)
返回多维数组的维度
>>> nd = np.random.randint(1,10,size=(2,5))
>>> nd.ndim
2
2、形状(shape)
返回多维数组的形状
>>> nd = np.random.randint(1,10,size=(2,5))
>>> nd.shape
(2, 5)
3、个数(size)
返回多维数组的里总元素的个数
>>> nd = np.random.randint(1,10,size=(2,5))
>>> nd.size
10
4、类型(dtype)
返回多维数组里数据的类型
>>> nd = np.random.randint(1,10,size=(2,5))
>>> nd.dtype
dtype('int32')
五、matplotlib 库
一个用来绘图的库
import matplotlib.pyplot as plt
1)plt.imread(“图片路径”)
功能: 将图片加载后返回一个维数组
>>> jin = plt.imread("./jin.png")
>>> jin
array([[[0.24313726, 0.24313726, 0.24705882],
...,
[0.7294118 , 0.7294118 , 0.7294118 ]]], dtype=float32)
>>> jin.shpae
(273, 411, 3)
'''
这是一个三维数组
第一层代表将图片分成273行,
第二层代表将图片的第一层的每一行分为411列,
第三层代表将每一像素点中的(R,G,B)
注意:有些图片加载后最内层有4个元素,分别是(R,G,B,A[阿尔法/透明度])
'''
2)plt.imshow(ndarray)
功能: 将多维数组渲染为一张图片
>>> plt.imshow(nd) #将加载后的多维数组传入就可以将图片渲染出来
'''
有的图片加载出来之后数据范围在0-255之间的需要将数据/255之后转化为0-1之间的就可以和0-1的图片进行合并操作
'''
这里就可以将图片进行处理(反转,拉伸,改色)等操作
六、ndarray的基本操作
1、索引
1)基本索引
基本索引:一维与列表完全一致 多维同理
>>> nd = np.random.randint(0,10,size=5)
>>> nd
array([7, 0, 8, 0, 1])
>>> nd[0]
7
>>> list = [[4, 2, 5, 0],
... [0, 7, 5, 7],
... [6, 9, 6, 5]]
>>> list[0][0]
4
2)高级索引
多维数组 还有 整数 数组 形式的索引
一般找数组中的值时,从最内层想外层找比较容易。
>>> nd = np.random.randint(0,10,size=(5,4))
>>> nd
array([[8, 0, 5, 4],
[2, 6, 4, 4],
[8, 0, 6, 0],
[3, 7, 2, 7],
[8, 8, 8, 3]])
>>> nd[0,-1] #可以将索引写到一个列表中
4
>>> nd[-2,[1,2]] #取最内层的元素,顺序任意,次数任意。
array([7, 2])
>>> nd[4,[0,3,3,3]]
array([8, 3, 3, 3])
2、切片
1)基本切片
基本切片:一维与列表完全一致 多维同理
>>> nd = np.random.randint(0,10,size=5)
>>> nd
array([0, 8, 0, 9, 3])
>>> nd[1:2]
array([8])
>>> nd[:3]
array([0, 8, 0])
>>> nd[:]
array([0, 8, 0, 9, 3])
>>> nd[::-1]
array([3, 9, 0, 8, 0])
2) 高级索引
ndarray[ 层级1 , 层级2, …]
切片:
ndarray[ 层级1的起始值:层级1的终止值:层级1的步长, 层级2的起始值:层级2的终止值:层级2的步长, …]
>>> nd = np.random.randint(0,10,size=(2,5,5))
>>> nd
array([[[4, 0, 7, 9, 2],
[7, 9, 0, 8, 9],
[6, 3, 2, 1, 1],
[9, 5, 9, 5, 5],
[0, 1, 0, 1, 5]],
[[6, 8, 8, 9, 2],
[7, 4, 6, 5, 4],
[6, 1, 2, 9, 4],
[4, 7, 8, 4, 9],
[9, 0, 4, 5, 4]]])
>>> nd[0:1]
array([[[4, 0, 7, 9, 2],
[7, 9, 0, 8, 9],
[6, 3, 2, 1, 1],
[9, 5, 9, 5, 5],
[0, 1, 0, 1, 5]]])
>>> nd[0:2,0:1]
array([[[4, 0, 7, 9, 2]],
[[6, 8, 8, 9, 2]]])
>>> nd[0:2,:,0:2]
array([[[4, 0],
[7, 9],
[6, 3],
[9, 5],
[0, 1]],
[[6, 8],
[7, 4],
[6, 1],
[4, 7],
[9, 0]]])
3、变形
a.reshape(shape, order=’C’)
功能:将已有的多维数组的形状进行改变
'''
shape:要变成的形状
注意:变成的形状的size(个数)必须与原数据的size(个数)相同
'''
>>> nd = np.random.randint(1,5,size=(3,4))
>>> nd
array([[2, 1, 3, 1],
[3, 1, 2, 3],
[3, 3, 1, 1]])
>>> nd.reshape(2,6)
array([[2, 1, 3, 1, 3, 1],
[2, 3, 3, 3, 1, 1]])
4、连接
concatenate((a1, a2, …), axis=0, out=None)
'''
参数:a1,a2,...为要连接的多维数组
axis:连接轴(默认为0,以X轴为中心轴连接,1,以Y轴为中心轴连接)
'''
>>> nd = np.random.randint(0,10,size=(3,4))
>>> np.concatenate((nd,nd))
array([[5, 1, 3, 2],
[9, 9, 6, 4],
[5, 8, 3, 3],
[5, 1, 3, 2],
[9, 9, 6, 4],
[5, 8, 3, 3]])
>>> np.concatenate((nd,nd),axis=1)
array([[5, 1, 3, 2, 5, 1, 3, 2],
[9, 9, 6, 4, 9, 9, 6, 4],
[5, 8, 3, 3, 5, 8, 3, 3]])
5、切分
np.split(ary, indices_or_sections, axis=0)
'''
ary:要进行切分的数组
indices_or_sections:用来指定要切分成及部分,或者在哪里切分
axis:用来指定以那个轴来切分(默认为0,以Y轴分为两半[横着劈开],1,以X轴分为两半[竖着劈开])
'''
#平均分为2份 (要分的数组必须是分后完整的均分)
>>> nd = np.random.randint(0,10,size=(6,4))
>>> np.split(nd,indices_or_sections=2)
[array([[3, 4, 2, 2],
[3, 1, 7, 0],
[1, 6, 1, 1]]), array([[4, 4, 1, 2],
[2, 2, 0, 8],
[6, 9, 8, 4]])]
#指定索引处分割
>>> np.split(nd,indices_or_sections=[1,2,5])
[array([[3, 4, 2, 2]]), array([[3, 1, 7, 0]]), array([[1, 6, 1, 1],
[4, 4, 1, 2],
[2, 2, 0, 8]]), array([[6, 9, 8, 4]])]
6、副本
浅拷贝
两个变量同时指向内存中同一个位置,id相同
改变一个变量,另一个变量跟着改变
>>> nd = np.random.randint(0,10,size=5)
>>> nd
array([0, 8, 6, 3, 3])
>>> nd1 = nd
>>> nd1[1] = 2
>>> nd
array([0, 2, 6, 3, 3])
>>> id(nd),id(nd1)
(1381152210816, 1381152210816)
深拷贝(副本)
完全拷贝,两个变量分别指向不同内存地址,id不相同
>>> nd3 = nd.copy()
>>> nd3
array([0, 2, 6, 3, 3])
>>> id(nd3),id(nd)
(1381152210656, 1381152210816)
七、ndarray的聚合操作
1、求和
np.sum(ndarray)
功能:求多维数组中所有元素的和
>>> nd = np.random.randint(0,10,size=(2,3))
>>> np.sum(nd)
27
np.nansum(ndarray)
NAN:not a number 特性:任何数和nan相加为nan
功能: 多维数组求和时,有nan则将nan视为0
>>> nd = np.array([1,2,3,np.NAN])
>>> nd
array([ 1., 2., 3., nan])
>>> np.sum(nd)
nan
>>> np.nansum(nd)
6.0
2、最大值,最小值
np.max(ndarray)
np.min(ndarray)
功能:求多维数组中所有元素中的最大值/最小值
>>> nd = np.random.randint(0,10,size=(2,3))
>>> np.max(nd)
8
>>> np.min(nd)
1
3、其他聚合操作
np.any(ndarray, axis=None, …)
功能:看所有的值中有没有True
一般在数据过滤时用到
'''
ndarray: 要查看的数组
axis : 以哪个轴为中心查看
'''
nd = array([[8, 3, 5, 3],
[0, 9, 6, 9],
[1, 4, 7, 6],
[6, 4, 6, 6],
[0, 4, 2, 4],
[8, 4, 1, 7]])
>>> np.any(nd,axis=0)
array([ True, True, True, True])
>>> np.any(nd,axis=1)
array([ True, True, True, True, True, True])
np.all(ndarray)
功能:查看是不是所有的都是True
>>> np.all(nd)
False
>>> np.all(nd,axis=0)
array([False, True, True, True])
>>> np.all(nd,axis=1)
array([ True, False, True, True, False, True])
np.all(ndarray)
功能:按照条件查询,返回索引位置
>>> nd
array([[0, 5, 3, 9, 9],
[5, 7, 0, 1, 2],
[7, 7, 5, 1, 3],
[0, 8, 2, 8, 4],
[9, 1, 2, 7, 9]])
>>> np.argwhere(nd == 3)
array([[0, 2],
[2, 4]], dtype=int64)
>>>
八、ndarray的矩阵操作
1、基本矩阵操作
1)算术运算符(加减乘除)
给矩阵整体加/减/乘/除因为矩阵的广播机制,使每个元素都会操作。
>>> nd
array([[0, 5, 3, 9, 9],
[5, 7, 0, 1, 2],
[7, 7, 5, 1, 3],
[0, 8, 2, 8, 4],
[9, 1, 2, 7, 9]])
>>> nd + 1
array([[ 1, 6, 4, 10, 10],
[ 6, 8, 1, 2, 3],
[ 8, 8, 6, 2, 4],
[ 1, 9, 3, 9, 5],
[10, 2, 3, 8, 10]])
2)矩阵积 np.dot()
计算方法:左边的第一行和右边的所有列进行计算将结果横着写,计算完左边第一行后再计算第二行,将结果从第二行开始写。
'''
矩阵运算注意点:
AB 如果想运算
A有多少列 B就要有多少行 这样才能对应位置相乘
如果A是 n行m列 B是 i行j列 (i的值要等于m)
乘出来的结果 是 n行j列 的矩阵
'''
>>> nd1 = np.random.randint(1,10,size=(5,4))
>>> nd2 = np.random.randint(1,10,size=(4,3))
>>> nd1
array([[8, 2, 8, 5],
[1, 9, 9, 9],
[3, 3, 3, 8],
[3, 6, 3, 2],
[8, 7, 9, 1]])
>>> nd2
array([[7, 4, 1],
[1, 1, 7],
[4, 9, 5],
[6, 2, 3]])
>>> np.dot(nd1,nd2)
array([[120, 116, 77],
[106, 112, 136],
[ 84, 58, 63],
[ 51, 49, 66],
[105, 122, 105]])
3)ndarray广播机制
规则:缺失元素使用已有值填充
>>> m = np.ones((2,3))
>>> a = np.arange(1,4,1)
>>> m
array([[1., 1., 1.],
[1., 1., 1.]])
>>> a
array([1, 2, 3])
>>> m + a
array([[2., 3., 4.],
[2., 3., 4.]])
九、ndarray的排序
1、快速排序
np.sort() 与 ndarray.sort()
'''
区别:
np.sort() 不改变原有数组,返回一个新的数组
ndarray.sort() 改变原有的数组,不返回数据
'''
>>> nd = np.random.randint(0,10,size=(3,5))
>>> nd
array([[0, 8, 0, 7, 1],
[9, 0, 2, 6, 2],
[4, 9, 7, 9, 1]])
>>> np.sort(nd) #返回一个新的数组
array([[0, 0, 1, 7, 8],
[0, 2, 2, 6, 9],
[1, 4, 7, 9, 9]])
>>> nd #原数组保持不变
array([[0, 8, 0, 7, 1],
[9, 0, 2, 6, 2],
[4, 9, 7, 9, 1]])
>>> nd.sort() #不返回数据
>>> nd #改变原来的数组排序
array([[0, 0, 1, 7, 8],
[0, 2, 2, 6, 9],
[1, 4, 7, 9, 9]])
2、部分排序
np.partition(a, kth, axis=-1)
功能:对数组内的部分数据进行排序
'''
a:要排序的多维数组
kth:想要的到的数据的个数
axis:轴线(默认为-1,以Y轴为中心进行排序)
kth:为正数时,得到的数组的 前 几个是最 小 的
kth:为负数时,得到的数组的 后 几个是最 大 的
'''
>>> nd
array([[15, 0, 44, 18, 39],
[35, 44, 93, 68, 70],
[49, 70, 70, 17, 71]])
>>> np.partition(nd,kth=2)
array([[ 0, 15, 18, 44, 39],
[35, 44, 68, 93, 70],
[17, 49, 70, 70, 71]])
>>> np.partition(nd,kth=-2)
array([[18, 15, 0, 39, 44],
[68, 35, 44, 70, 93],
[17, 49, 70, 70, 71]])