numpy模块的使用numpy:一个在Python中做科学计算的基础库,重在数值计算,也是大部分Python科学计算库的基础库,多用于在大型、多维数组上执行数值运算
数组
创建数组数组的数据类型数组的形状数组的计算数组的拼接与分割数组的行列交换 轴(axis)numpy读取数据和索引
读取本地数据numpy中的转置numpy的切片numpy中数值的修改numpy中的布尔索引numpy中的三元运算符 numpy中的nan和inf
naninf numpy中常用的统计函数numpy中的其他方法
创建特殊数组numpy生成随机数numpy中的copy和view
数组 创建数组可以使用numpy的array()、array(range())、arange()方法创建数组,其中arange()相当于array(range())
import numpy as np
t1 = np.array([1, 2, 3])
print('t1:', t1) # t1: [1 2 3]
print('type(t1):', type(t1)) # type(t1):
t2 = np.array(range(4))
print('t2:', t2) # t2: [0 1 2 3]
# arange()相当于array(range())
t3 = np.arange(4)
print('t3:', t3) # t3: [0 1 2 3]
t4 = np.arange(2, 10, 3)
print('t4:', t4) # t4: [2 5 8]
数组的数据类型
查看、设置、修改数组的数据类型
1> 使用数组对象的dtype属性可以查看数组的数据类型
2> 创建数组时使用dtype参数可以设置数组的数据类型
3> 使用数组对象的astype()方法可以修改数组的数据类型,原数组不变,返回一个修改后的新数组
4> 使用np.round()可以修改数组中浮点数的小数位数
import numpy as np """查看数组的数据类型""" t1 = np.arange(3) print(t1.dtype) # int32 """设置数组的数据类型""" # 以下三种方法设置的结果是相同的:float16,[1. 4. 7.] t2 = np.arange(1, 10, 3, dtype='float16') t3 = np.arange(1, 10, 3, dtype=np.float16) t4 = np.arange(1, 10, 3, dtype='f2') """修改数组的数据类型""" t5 = np.array([1, 0, 1, 0, 2], dtype='bool') print(t5.dtype, t5) # bool [ True False True False True] t6 = t5.astype(np.int8) print(t6.dtype, t6) # int8 [1 0 1 0 1] print(t5.dtype, t5) # bool [ True False True False True] """修改数组中浮点数的小数位数""" t7 = np.array([random.random() for _ in range(3)]) print(t7.dtype, t7) # float64 [0.7459032 0.7121498 0.70406119] t8 = np.round(t7, 2) print(t8.dtype, t8) # float64 [0.75 0.71 0.7 ]
数组常见的数据类型
| 类型 | 类型代码 | 说明 |
|---|---|---|
| int8、uint8 | i1、u1 | 有符号和无符号的8位(1个字节)整型 |
| int16、uint16 | i2、u2 | 有符号和无符号的16位(2个字节)整型 |
| int32、uint32 | i4、u4 | 有符号和无符号的32位(4个字节)整型 |
| int64、uint64 | i8、u8 | 有符号和无符号的64位(8个字节)整型 |
| float16 | f2 | 半精度浮点数 |
| float32 | f4或f | 标准的单精度浮点数,与C的float兼容 |
| float64 | f8或d | 标准的双精度浮点数,与C的double和Python的float对象兼容 |
| float128 | f16或g | 扩展精度浮点数 |
| complex64、complex128、complex256 | c8、c16、c32 | 分别用两个32位、64位或128位浮点数表示的复数 |
| bool | ? | 存储True和False值的布尔类型 |
import numpy as np t1 = np.array([1,2,3]) # 创建一个1行3列的数组(一维数组) t1.shape # 查看数组的形状 -> (3,) t2 = np.array([[1,2,3],[4,5,6]]) # 创建一个2行3列的数组(二维数组) t2.shape # 查看数组的形状 -> (2, 3) t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) # 创建一个三维数组 t3.shape # 查看数组的形状 -> (2, 2, 3) t3.reshape((3,4)) # 修改数组的形状,将t3从三维数组变为二维数组,返回一个新数组,t3本身不变 t3.flatten() # 将数组展开为一维数组,返回一个新数组,t3本身不变 t4 = np.array(range(12)) # 创建一个一维数组 t4.reshape((2,3,2)) # 修改数组的形状,将t4从一维数组变为三维数组,返回一个新数组,t4本身不变 t3.reshape((12,)) # 修改为一维数组 t3.reshape((12,1)) # 修改为二维数组 t3.reshape((1,12)) # 修改为二维数组,和上面结果不同数组的计算
数组和数的计算
因为numpy的广播机制,在运算过程中,数组和数的计算会被广播到所有元素上面
import numpy as np t1 = np.array([[1,2,3],[4,5,6]]) # 创建一个二维(2, 3)数组 t2 = t1-2 # 计算后会返回一个新的数组,原数组不变 -> [[-1 0 1] [ 2 3 4]]
注:数组和数的计算中,0可以当做除数,0/0=nan,正数/0=inf,负数/0=-inf,其中nan意为not a number(不是一个数字),inf意为infinite(无穷的)
数组和数组的计算
当数组的形状相同时,对应位置的数进行计算
t1 = np.array([[1, 2, 3], [4, 5, 6]]) t2 = np.array([[100, 200, 300], [400, 500, 600]]) print(t1+t2) # [[101 202 303] [404 505 606]]当数组的形状不同时,如果有一个维度是相同的,那么就以此维度为基准进行计算;如果没有相同的维度,那么就会报错
t1 = np.array([[1, 2, 3], [4, 5, 6]]) t3 = np.array([10, 20, 30]) print(t1+t3) # [[11 22 33] [14 25 36]] t4 = np.array([[100], [200]]) print(t1+t4) # [[101 102 103] [204 205 206]] t5 = np.array(range(6)) # t1+t5 # ValueError: operands could not be broadcast together with shapes (2,3) (6,) t6 = np.array(range(9)).reshape((3, 3)) # t1+t6 # ValueError: operands could not be broadcast together with shapes (2,3) (3,3)
广播原则:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行
(2,3,5,3,6,2) (4,6,2) 不可以计算 (2,3,5,3,6,2) (3,6,2) 可以计算 (2,3,5,3,6,2) (3,6,2,1) 不可以计算 (2,3,5,3,6,2) (1,3,6,2) 可以计算 (2,3,5,3,6,2) (2,) 可以计算 (2,3,5,3,6,2) (1,2) 可以计算 (2,3,5,3,6,2) (2,1) 不可以计算数组的拼接与分割
np.vstack((t1, t2)):竖直拼接(vertically),参数是需要拼接的数组组成的元组,返回拼接后的数组
np.hstack((t1, t2)):水平拼接(horizontally),参数是需要拼接的数组组成的元组,返回拼接后的数组
np.vsplit(t3, 2):竖直分割(vertically),是竖直拼接的逆向操作,参数是需要分割的数组和分割的份数,默认均等分割,返回分割后的数组组成的列表
np.hsplit(t4, 4):水平分割(horizontally),是水平拼接的逆向操作,参数和返回值同竖直分割相同
import numpy as np t1 = np.arange(12).reshape((2, 6)) t2 = np.arange(12, 24).reshape((2, 6)) """拼接""" t3 = np.vstack((t1, t2)) t4 = np.hstack((t1, t2)) """分割""" l1 = np.vsplit(t3, 2) l2 = np.hsplit(t4, 4)数组的行列交换
行列交换的意思是指将行与行或者列与列的位置进行互换
import numpy as np t = np.arange(12).reshape((3, 4)) t[[1, 2], :] = t[[2, 1], :] # 行交换 t[:, [0, 2]] = t[:, [2, 0]] # 列交换轴(axis)
轴的解释:在numpy中可以理解为方向,使用数字0,1,2…表示,对于一个一维数组,只有一个0轴,对于二维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴
如:np.arange(0,10).reshape((2,5)),reshape中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2*5一共10个数据
语法:np.loadtxt(fname, dtype=np.float, delimiter=None, skiprows=0, usecols=None, unpack=False)
| 参数 | 解释 |
|---|---|
| frame | 文件、字符串或产生器,可以是.gz或bz2的压缩文件 |
| dtype | 数据类型,可选,文件的内容以数据类型计入数组中,默认是np.float |
| delimiter | 分隔字符串,默认是任何空格 |
| skiprows | 跳过前x行,一般用于跳过第一行表头 |
| usecols | 读取指定的列,索引,元组类型 |
| unpack | 默认为False,表示读入数据只写入一个数组变量;为True,表示读入属性将分别写入不同数组变量(可以理解为行列转换,默认的行列和文件中的相同) |
import numpy as np file_path = './aaaa/bbbb.csv' t1 = np.loadtxt(file_path, delimiter=',', dtype='int', unpack=True)numpy中的转置
转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据。在二维数组中转置的简单理解就是把行和列进行转换,行变为列,列变为行
转置的方法有三种:t.transpose()、t.T、t.swapaxes(1,0)
import numpy as np t = np.arange(24).reshape((4,6)) # 以下三种方法转置的结果相同 t.transpose() t.T t.swapaxes(1,0) # 交换轴numpy的切片
numpy的切片和Python中列表的切片类似,不同的是需要在多个维度上进行操作
import numpy as np file_path = './aaaa/bbbb.csv' t1 = np.loadtxt(file_path, delimiter=',', dtype='int') """取行和列""" # 取第3行第4列的值 a = t1[2, 3] # 170708,类型为# 取第3行到第5行,第2列到第4列的值(取的是交叉点的数据) b = t1[2:5, 1:4] # 类型为 # 取多个不相邻的点 # 取的结果是(0, 0), (2, 1), (2, 3)位置的值 c = t1[[0, 2, 2], [0, 1, 3]] # [4394029 576597 170708]
可以看到,在上面的代码中[]中的,前面表示行,,后面表示列
numpy中数值的修改数组中修改行列的值,只需要取到对应的行列然后赋予一个新的值即可
import numpy as np t = np.arange(24).reshape((4, 6)) t[:, 2:4] = 100 # 取到对应的数值然后赋予一个新的值numpy中的布尔索引
import numpy as np t = np.arange(24).reshape((4, 6)) print(t) # t的结果如下: # [[ 0 1 2 3 4 5] # [ 6 7 8 9 10 11] # [12 13 14 15 16 17] # [18 19 20 21 22 23]] t1 = t < 10 print(t1) # t1的结果如下: # [[ True True True True True True] # [ True True True True False False] # [False False False False False False] # [False False False False False False]] t[t < 10] = 0 print(t) # 通过布尔索引筛选,修改数值之后的t如下: # [[ 0 0 0 0 0 0] # [ 0 0 0 0 10 11] # [12 13 14 15 16 17] # [18 19 20 21 22 23]]numpy中的三元运算符
import numpy as np t = np.arange(24).reshape((4, 6)) print(t) # t的结果如下: # [[ 0 1 2 3 4 5] # [ 6 7 8 9 10 11] # [12 13 14 15 16 17] # [18 19 20 21 22 23]] # np.where()为numpy中的三元运算符, # 这句代码的意思为: # 数组t中的值,如果小于10,那么将其修改为0,否则修改为10 t1 = np.where(t < 10, 0, 10) print(t1) # t1的结果如下: # [[ 0 0 0 0 0 0] # [ 0 0 0 0 10 10] # [10 10 10 10 10 10] # [10 10 10 10 10 10]]numpy中的nan和inf nan
nan(NAN,Nan):not a number,表示不是一个数字,数据类型为float
什么时候会出现nan
1> 读取本地的文件为float的时候,如果有缺失,就会出现nan
2> 做不合适计算的时候(比如无穷大减去无穷大)
3> 0/0的结果为nan
nan的性质
1> 两个nan是不相等的
2> 利用上述特性判断数组中nan的数量
import numpy as np t = np.array([1, 2, np.nan, 3, 4]) a = np.count_nonzero(t != t) # 得到nan的数量 -> 1
3> 判断一个数字是否是nan,使用np.isnan()方法,是nan则返回True,否则返回False,同样也可以用来判断nan的数量
import numpy as np t = np.array([1, 2, np.nan, 3, 4]) b = np.count_nonzero(np.isnan(t)) # 得到nan的数量 -> 1
4> nan和任何值的计算结果都为nan
import numpy as np t = np.array([1, 2, np.nan, 3, 4]) c = sum(t) # 计算数组t的和 -> nan
实际问题中nan的处理方式
因为nan和任何值的计算结果都为nan,所以实际问题中遇到nan会影响数据的处理,而如果单纯地把nan替换为0又会影响均值等数据的准确性,所以更好的方法是将nan(缺失的值)替换为均值(中值)或者直接删除有nan(有缺失值)的一行或一列
def fill_ndarray(t):
"""
给定一个数组,通过遍历数组中的每一列,将列中为nan的位置替换为当前列中不为nan的均值,返回替换后的数组,
return t
"""
for i in range(t.shape[1]): # 遍历每一列
temp_col = t[:, i] # 当前的一列
nan_num = np.count_nonzero(temp_col != temp_col) # 统计当前列中nan的数量
if nan_num: # 为True说明当前列中有nan
# 取出当前列中不为nan的值
temp_no_nan_col = temp_col[temp_col == temp_col]
# 选中当前列中为nan的位置,把值赋值为不为nan的均值
temp_col[np.isnan(temp_col)] = temp_no_nan_col.mean()
return t
inf
inf(-inf,inf):infinity,无穷的。inf表示正无穷,-inf表示负无穷,数据类型为float
一个数字除以0的结果为inf,正数/0=inf,负数/0=-inf
求和:t.sum(axis=None)
均值:t.mean(axis=None),受离群点的影响较大
中值:np.median(t,axis=None)
最大值:t.max(axis=None)
最小值:t.min(axis=None)
极差:np.ptp(t,axis=None),即最大值和最小值之差
标准差:t.std(axis=None)
以上函数默认返回多维数组全部数值的统计结果,如果指定axis则返回当前轴上的结果
创建一个全为0的数组:np.zeros((3,4))
创建一个全为1的数组:np.ones((3,4))
创建一个对角线全为1的正方形数组(方阵):np.eye(3)
获取最大值、最小值的位置:np.argmax(t,axis=0)、np.argmin(t,axis=1)
| 语法 | 说明 |
|---|---|
| np.random.rand(d0,d1,d2,...,dn) | 创建d0到dn维度的均匀分布的随机数数组,浮点数,范围为0-1 |
| np.random.randn(d0,d1,d2,...,dn) | 创建d0到dn维度的标准正态分布的随机数,浮点数,平均数为0,标准差为1 |
| np.random.randint(min,max,(shape)) | 随机生成[min,max)之间的整数组成数组,形状是shape |
| np.random.uniform(min,max,(shape)) | 随机生成[min,max)之间的浮点数组成数组,形状是shape |
| np.random.normal(loc,scale,(shape)) | 从指定正态分布中随机生成浮点数,分布中心为loc,标准差为scale,形状为shape |
| np.random.seed(s) | 随机数种子,s是给定的种子值。设定相同的种子值之后,后续每次生成的随机数都和第一次生成的相同 |
a = b:完全不复制,a和b相互影响a = b[:]:视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的a = b.copy():复制,a和b互不影响



