numpy
可以帮助我们处理数值型的数据,注意,是数值型
用于处理数组(或者叫做矩阵)
创建数组(或矩阵)
可以先简单的通过列表创建数组
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
来看看输出了什么
打印出了一个像列表的数据,但是中间没有逗号~
还有其他一些简单的创建方式
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
我们可以发现t2和t3其实是一样的,类型也都是和t1一样的
当然np.arange()
也可以像range()
一样取步长
数组元素的数据类型
我们并没有指定这些元素的数据类型
我们来看看它们里面元素的数据类型(因电脑位数不同而会有所不同)
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看数组元素的数据类型
print(t3.dtype)
这里打印出是int32位的
还有其他更多的数据类型
在实际形况中,我们可以指定数组里面的数据类型,可以达到节省空间的目的
创建时指定数据类型
array()
函数里面有个dtype
参数可以指定元素的数据类型
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看数组元素的数据类型
print(t3.dtype)
print("*"*50)
# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
好像这个bool类型的蛮有趣的,我们来看看它是怎么样的
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看数组元素的数据类型
print(t3.dtype)
print("*"*50)
# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool类型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
打印出来效果是这样的
调整数据类型
需要astype()
函数,里面传入调整后的数据类型就好了
import numpy as np
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看数组元素的数据类型
print(t3.dtype)
print("*"*50)
# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool类型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
t6 = t5.astype('int8')
print(t6)
print(t6.dtype)
numpy中的小数
np.round()
可以帮助取几位小数
import numpy as np
import random
t1 = np.array([1,2,3])
print(t1)
print(type(t1))
t2 = np.array(range(10))
print(t2)
t3 = np.arange(10)
print(t3)
# 查看数组元素的数据类型
print(t3.dtype)
print("*"*50)
# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)
# numpy中的bool类型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5)
print(t5.dtype)
t6 = t5.astype('int8')
print(t6)
print(t6.dtype)
# numpy中的小数
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
t8 = np.round(t7,2)
print(t8)
数组的形状
什么是数组的形状?
先来看个例子
import numpy as np
t1 = np.arange(12)
print(t1)
print(t1.shape)
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)
原来数组的形状就是它是描述它的纬度
一维的数组打印出来只有一个数字,二维的两个数组打印出来有两个数字
那三维的是不是三个呢,我们来看看
import numpy as np
# 一维
t1 = np.arange(12)
print(t1)
print(t1.shape)
# 二维
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)
# 三维
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)
三维打印出来的(2, 2, 3), 第一个2表示块数,相当于是空间坐标的Z轴,后面的(2,3)就是平面的2行3列
调整数组的纬度
我们可以将一维的变成2维的,也可以将2维的变成一维的
用到了reshape()
函数
import numpy as np
t4 = np.array(range(12))
print(t4)
t4 = t4.reshape(3,4)
print(t4)
当然转换的要求要保证前后数量一致,不然就报错
一维转三维
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
print(t5)
三维的转二维的
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
print(t5)
print(t5.reshape(4,6))
转换的过程大概是三维的先压平成一维的,然后从一维的变成二维的
二维边一维
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
t7 = t6.reshape(24,)
print(t7)
想一想,为什么不是t6.reshape(1,24)
我们来打印一下结果你就会发现它其实是二维的
如果有一个二维数组非常大,我想把它变成一维,是不是要知道元素的个数
在二维数组中,shape[0]
表示有多少行,shape[1]
表示有多少列
那么我们可以这样
t6 = t5.reshape(t5.shape[0]*t5.shape[1],)
还有一种简便的方法变成一维
有个函数叫做flatten()
,碾平的意思
这种方式不需要传入元素的个数
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
t7 = t6.flatten()
print(t7)
数组的计算
一个数组和一个数计算,所有的元素都会与它运算
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)
t7 = t6 + 1
print(t7)
如果除于0呢,看看会不会出问题
import numpy as np
t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)
t7 = t6/0
print(t7)
程序只是报了warning,还是可以显示的,只是这结果不对劲呀
nan
意思not a number, 它不是一个数,可以是其他东西,比如字符串,香蕉苹果啥的
inf
意思是无穷大的意思,还有-inf是无穷小
一个数组和一个相同形状的数组运算,对应位置独立运算,这个很好理解
如果是不同纬度的数组相互计算,如果存在某个维度上一致,那么是可以计算的
我们来看看
import numpy as np
t1 = np.arange(6)
t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)
那么这两个数组可以计算吗?
是可以的,因为在行的方向上的纬度是一样的
import numpy as np
t1 = np.arange(6)
t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)
print(t1+t2)
如果是列方向纬度一致,也是一样的
三维的和二维的计算也是同一个道理
轴
在numpy中可以理解为方向,用0,1,2数字表示
对于一个一维数组,只有一个0轴
二维数组,有0轴和1轴,0轴表示行方向,1轴表示列方向
三维数组,有0,1,2轴,0表示高度(Z轴),1表示行方向,2表示列方向
转置
numpy中转置有多种方法,这里介绍常用的两种方法
第一种是transpose()
第二种是属性T
import numpy as np
t1 = np.arange(12).reshape(3,4)
print(t1)
print(t1.transpose())
print(t1.T)
索引和切片
numpy中索引从0开始的
取某一行,注意取出来的是一维的
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第三行
print(t1[2])
取连续的多行
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2: 3 行
print(t1[1:3])
取不连续的多行
都加了一个方括号
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2行和第4行
print(t1[[1,3]])
取某一列,注意选出来的是一维的
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第1列
print(t1[:,0])
取连续的几列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第2:4列
print(t1[:,1:4])
取不连续的多列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第1列和第3列
print(t1[:,[0,2]])
取多行多列
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
# 取第3行第4列的值,虽然是一个数但类型要注意
a = t1[2,3]
print(a)
print(type(a))
# 取第2:4行,第3到第6列
print(t1[1:4,2:6])
# 取多个不相邻的点,有些特殊
# 取(0,2),(3,1)值
print(t1[[0,3],[2,1]])
对数组的修改
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
t1[:,1:3] = 0
print(t1)
如果要把数组中小于10的修改为10怎么写?
先看下面程序
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(t1<10)
可以看出那些是小于10的,这就是很常用的bool索引
如果要把数组中小于10的修改成10,那么这就很简单了
t1[t1<10] = 10
如果想把小于10的改为0,大于10的改为10
按照上面的方法,我们要写两行
这里介绍一个where()
函数,一行就能解决
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(np.where(t1<10,0,10))
问题升级
如果我想把小于10的改为10,大于20的改为20呢?
当然bool索引可以做,也是写两行
这里介绍一个clip()
裁剪函数
import numpy as np
t1 = np.arange(24).reshape(4,6)
print(t1)
print("*"*50)
print(t1.clip(10,18))
nan和inf
nan就是not a number,表示不是一个数字
numpy中出现nan的情况:
当我们读取本地文件为float的时候,如果有缺少,就会出现nan
当做了一个不合适的计算的时候,比如( 无穷大(inf)减去无穷大)
inf表示正无穷,-inf表示负无穷
什么时候会出现inf:
当一个数字处于0 (python中会直接报错,而numpy会出现inf)
在numpy中如何指定一个数为nan和inf
import numpy as np
a = np.nan
print(a)
print(type(a))
b = np.inf
print(b)
print(type(b))
发现它们都是float
类型
numpy中nan的注意点
两个nan是不想等的
import numpy as np
print(np.nan == np.nan)
这个性质有一些特殊用途
比如,可以判断数组中nan的个数
先介绍count_nonzero()
数组是统计非0的个数
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
print(a!=a)
# 统计a中nan的个数
print(np.count_nonzero(a!=a))
还可以这样统计nan的个数
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
print(np.isnan(a))
# 统计a中nan的个数
print(np.count_nonzero(np.isnan(a)))
这样可以把为nan的地方换成别的值,比如0
a[np.isnan(a)] = 0
nan和任意值运算都为nan
这里介绍一个np.sum()
函数,统计和的
import numpy as np
a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)
# 计算数组a的和
print(np.sum(a))
# 计算行方向上的值
print(np.sum(a,axis=0))
因为nan不能参与计算,那么一般都是把nan替换次别的值
有些时候单纯的替换成0是不合适的
更一般是替换成均值(中值),或者直接删去
那么问题来了
怎么计算一组数据的中值或均值?
如何删除有缺失的那一行(列) ?【在pandas中介绍】
numpy中常用的统计函数
将数组中nan填充为均值
import numpy as np
def fill_ndarray(t1):
'''
把数组中有nan的地方填充为均值
:param t1: 原始的二维数组
:return: 填充之后的数组
'''
# 遍历所有列
for i in range(t1.shape[1]):
# 当前列
cur_col = t1[:,i]
# 当前列中nan的个数
num_not_nan = np.count_nonzero(cur_col!=cur_col)
# 如果当前列有nan
if num_not_nan != 0:
# 当前列不为nan的ndarray
array_not_nan = cur_col[cur_col==cur_col]
# 把nan的位置赋值为均值
cur_col[np.isnan(cur_col)] = array_not_nan.mean()
return t1
if __name__ == '__main__':
# 创建一个二维数组,类型为float
t1 = np.arange(12).reshape(3,4).astype('float')
# 将t1数组里面部分值赋值为nan
t1[1,2:] = np.nan
print(t1)
t1 = fill_ndarray(t1)
print(t1)
数组拼接
竖直拼接np.vstack()
水平拼接np.hstack()
注意传入的是一个元组,就是有两层括号
import numpy as np
t1 = np.arange(10).reshape(2,5)
t2 = np.arange(10,20).reshape(2,5)
print(t1)
print(t2)
# 竖直拼接np.hstack((t1,t2))
t3 = np.vstack((t1,t2))
print(t3)
# 水平拼接
print(np.hstack((t1,t2)))
数组的行列交换
import numpy as np
t1 = np.arange(12).reshape(3,4)
print(t1)
# 第2行和第3行交换
t1[[1,2],:] = t1[[2,1],:]
print(t1)
#第1列和第3列交换
t1[:,[0,2]] = t1[:,[2,0]]
print(t1)
numpy更多好用的方法
创建一个全0的数组 np.zeros((3,4))
创建一个全1的数组 np.ones((3,4))
创建一个对角线为1的方阵 np.eye(5)
获取数组最大值,最小值的位置,可以指定方向
import numpy as np
t = np.array([[3,5,1,0],[6,3,8,9]])
print(t)
print(t.argmax())
print(t.argmax(axis=1))
print(t.argmin(axis=0))
随机数
numpy的注意点copy和view
- a=b完全不复制,a和b相互影响,即a和b共享一块内存
- a = b[:] ,视图操作,也是完全不复制
- a = b.copy(), 深拷贝,a和b互不影响