Numpy

介绍

  • Numpy(Numerical Python)是目前Python数值计算中最为重要的基础包。大多数计算包都提供了基于Numpy的科学函数功能,将Numpy的数组对象作为数据交换的通用语

    • 提供高效多维数组
    • 提供了基于数组的便捷算术操作以及广播机制
    • 对数据进行快速的矩阵计算
    • 对硬盘中数组数据进行读写操作
  • Numpy安装

    直接在dos命令行中pip install numpy 即可

    可参考官网:https://numpy.org/devdocs/user/quickstart.html

基本操作

  • 创建N维数组对象

    • numpy.array(object)
    1
    2
    3
    4
    import numpy as np
    li = [1,2,3,4]
    arr = np.array(li)
    arr
    • numpy.arange([start,] stop[, step,])
    1
    2
    3
    import numpy as np
    arr = np.arange(1,5)
    arr

数据类型

类型 类型代码 描述
int8,uint8 i1,u1 有符号和无符号的8数位整数
int16,uint16 i2,u2 有符号和无符号的16数位整数
int32,uint32 i4,u4 有符号和无符号的32数位整数
int64,uint64 i8,u8 有符号和无符号的64数位整数
float16 f2 半精度浮点数
float32 f4 标准单精度浮点数
float64 f8 标准双精度浮点数
bool ? 布尔值,存储True或False
string_ S ASCII字符串类型,eg:’S10’
unicode_ U Unicode类型,eg:’U10’
  • 查看数据类型
1
2
3
import numpy as np
arr = np.arange(1,5)
print(arr.dtype)
  • 指定数组类型

    • numpy.array(object,dtype=None)
    1
    2
    3
    import numpy as np
    arr = np.array([1,2,3],dtype='f8')
    print(arr.dtype)

数组形状

  • arr.ndim

    • 查看数组的维度,返回值为整数
  • arr.shape

    • 查看数组的形状,返回值为元组
1
2
3
4
5
6
7
import numpy as np
arr1 = np.arange(6)
#查看数组维度
print(arr1.ndim) #1

#查看数组形状 一行六列
print(arr1.shape) #(6,)
  • 重塑数组 arr.shape(shape,order=”C”)

    • shape为数组重塑形状

      order表示重塑方向

    • C顺序(行方向)重塑

      F顺序(列方向)重塑

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import numpy as np
    arr1 = np.arange(6)

    #reshape重塑形状
    arr4 = np.arange(6).reshape(2,3) #2行3列
    print(arr4) #arr4= [[0 1 2]
    # [3 4 5]]

    arr5 = np.arange(6).reshape(3,2,order='F') #3行2列 竖直取值
    print(arr5)

    #[[0 3]
    # [1 4]
    # [2 5]]
    #-1可以自动判断另一行或列数
    arr6 = arr1.reshape(-1,3)
    print(arr6)
    #[[0 1 2]
    # [3 4 5]]
    • 多维转一维

      • arr.flatten()

        arr.ravel()

1
2
3
4
5
6
7
8
import numpy as np
arr1 = np.arange(6)

#多维转一维
arr8 = np.arange(16).reshape(4,4)
arr9 = arr8.flatten() #扁平化 ravel也可以
print(arr9)
#[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
  • 数组转置与换轴
    • arr.transpose() # 转置
    • arr.T # 转置
    • arr.swapaxes() # 换轴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
arr = np.arange(16).reshape(4,4)

print(arr)
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]]
#arr.T转置 或arr.transpose arr.swapaxew(1,0) 交换轴
print(arr.T)
#[[ 0 4 8 12]
# [ 1 5 9 13]
# [ 2 6 10 14]
# [ 3 7 11 15]]
  • 浅拷贝与深拷贝

    • 浅拷贝arr.view()
    • 深拷贝arr.copy()
  • 其他函数

函数名 描述
array 将输入数据转换为ndarray数组,自动推断数据类型,默认复制所有输入数据
asarray 将输入数据转换为ndarray数组,但输入数据已经是ndarray则不再复制
arange python内建函数range的数组版,返回一个数组
zeros 根据给定形状和数据类型生成全0数组
ones 根据给定形状和数据类型生成全1数组
empty 根据给定形状和数据类型生成一个没有初始化数值的空数组
full 根据给定形状和数据类型生成指定数值的数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np

#生成一维三个元素都为0的数组 可传入元祖或整数
arr = np.zeros(3)
print(arr)
arr1 = np.zeros((2,3))
print(arr1)

# 生成全为1的数组
arr2 = np.ones(3)
print(arr2)
#生成2行三列
arr3 = np.ones((2,3))
print(arr3)
# arr4 = np.empty(4)
#生成一维3个4
arr5 = np.full(3,4)
print(arr5)
#生成三行三列的5
arr6 = np.full((3,3),5)
print(arr6)
#单位矩阵
arr7 = np.eye(3)
print(arr7)
#生成与arr相同的值都为1的数组
arr8 = np.ones_like(arr)
print(arr8)

数组运算

  • 数组与标量的算术操作

    数组与标量的算术操作会把计算参数传递给数组的每一个元素。

1
2
3
4
5
import numpy as np

arr1 = np.arange(6)+2
print(arr1)
#[2 3 4 5 6 7]
  • 两个等尺寸数组的算术操作

    两个等尺寸数组的算术操作实际上是逐元素操作。

1
2
3
4
5
6
7
import numpy as np

arr2 = np.arange(6).reshape(2,3)
#可进行对应位置加减乘除
print(arr2+arr2)
#[[ 0 2 4]
# [ 6 8 10]]
  • 广播机制:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np

arr2 = np.arange(6).reshape(2,3)
#广播机制 一个轴为1 另一轴数量相等 会向另一侧广播
arr3 = np.arange(3).reshape(1,3)
print(arr3) #[[0 1 2]]
print(arr2+arr3)

#[[0 2 4]
# [3 5 7]]
arr4 = np.arange(2).reshape(2,1)
print(arr2+arr4)
#[[0 1 2]
# [4 5 6]]
  • 数组拼接

    • np.vstack() 垂直拼接

      np.hstack() 水平拼接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import numpy as np
    #垂直拼接
    a1 = np.arange(12).reshape(2,6)
    a2 = np.arange(12,24).reshape(2,6)
    a3 = np.vstack((a1,a2))
    print(a3)
    #[[ 0 1 2 3 4 5]
    # [ 6 7 8 9 10 11]
    # [12 13 14 15 16 17]
    # [18 19 20 21 22 23]]
    #水平拼接
    a4 = np.hstack((a1,a2))
    print(a4)
    #[[ 0 1 2 3 4 5 12 13 14 15 16 17]
    # [ 6 7 8 9 10 11 18 19 20 21 22 23]]

数组切片

一维索引与切片

同python中的内建数据类型list一致。

  • 索引默认从0开始
  • 切片左闭右开
  • 步长为整数

二维索引与切片

  • 二维数组递归方式获取

  • 二维数组逗号分隔获取(行,列)

    • 取单行 arr[x1,:]
    • 取连续行 arr[x1:x2,:]
    • 取分开行 arr[[x1,x2],:]
    • 取子矩阵 arr[x1:x2,y1:y2]
    • 取点 arr[[x1,x2],[y1,y2]]

注意

  • 当有需要修改数组当中的值时,我们可以直接取值进行赋值。

  • 当数组与标量进行比较时,数组当中每个元素与标量进行比较,返回bool值。与此同时,该比较也可以作为索引,被称为布尔索引。比如arr[arr>20]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #取值
    import numpy as np
    a1 = np.arange(10)
    print(a1[2])
    print(a1[:2])
    print(a1[1::2])
    #二维切片
    a2 = np.arange(24).reshape(4,6)
    #取第二行
    print(a2[1])
    #取第二行的7
    print(a2[1][1]) #不常用
    # 行,列
    print(a2[1,:])
    #取2,3连续两行
    print(a2[1:3,:])
    #取2 4行
    print(a2[1::2,:])
    #神奇索引写法
    print(a2[[1,3],:])
    #取8 9 14 15
    print(a2[1:3,2:4])
    #布尔索引取值
    print(a2[a2>10])
    print(a2[(a2>10) & (a2<20)]) #需要确认优先级

将条件逻辑作为数组操作

numpy.where()函数是三元表达式 x if condition else y 的向量化版本。

  • np.where(condition, [x, y]) # 当满足条件,执行x,否则执行y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
arr = np.arange(16).reshape(4,4)
#条件逻辑作为数组操作 此为三元表达式 np.where(condition,[x,y]) 满足条件执行x否则y
arr1 = np.where(arr<10)
# print(arr1) #输出前项为索引行,后为索引列
arr2 = np.where(arr<10,0,10) #小于10变0 否则变10
arr3 = np.where(arr<10,0,arr) #小于10变0 否则不变
print(arr2)#[[ 0 0 0 0]
#[ 0 0 0 0]
#[ 0 0 10 10]
#[10 10 10 10]]


print(arr3)#[[ 0 0 0 0]
# [ 0 0 0 0]
# [ 0 0 10 11]
# [12 13 14 15]]
#np.clip(x,y) 小于x替换为x 大于y替换为y
arr4 = np.clip(arr,5,10)
print(arr4)#[[ 5 5 5 5]
# [ 5 5 6 7]
# [ 8 9 10 10]
# [10 10 10 10]]

Numpy操作本地数据

写入本地数据

  • np.savetxt(fname)

    • fname 文件路径
    • dtype 数据类型
    • delimiter 分隔符
    • fmt=’%.18e’ 写入文件的格式,例如:%d,%.2f,%.18e
    • converters 对数据预处理。比如{0:func}第0列进行func函数预处理
    • header 指定为表头
1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
'''
fname 文件路径
dtype 数据类型
delimiter 分隔符
fmt 写入文件格式
converters 对数据进行函数预处理
header 指定表头
'''
#40行 2列随机数据 size相当于reshape
arr = np.random.randint(0, 100, size=(40, 2))
#保存至csv 以','作为分隔符若不使用 则会认为是一个str fmt去除科学计数法 headerbiaotou comments去引号
np.savetxt('score.csv',arr,delimiter=',',fmt='%d',header='期中,期末',comments='')

读取本地数据

  • np.loadtxt(fname) # 加载文件

    • fname 文件路径
    • dtype 数据类型
    • delimiter 分隔符
    • skiprows 跳过行
    • comment 如果行的开头为 # 就会跳过该行
    • usecols 是指使用(0,2)两列
    • unpack 每一列当成一个向量输出,而不是合并在一起
    • converters 对数据预处理。比如{0:func}第0列进行func函数预处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
'''
fname 文件路径
dtype 数据类型
delimiter 分隔符
fmt 写入文件格式
converters 对数据进行函数预处理
header 指定表头
'''
#40行 2列随机数据 size相当于reshape
arr = np.random.randint(0, 100, size=(40, 2))
#保存至csv 以','作为分隔符若不使用 则会认为是一个str fmt去除科学计数法 headerbiaotou comments去引号
np.savetxt('score.csv',arr,delimiter=',',fmt='%d',header='期中,期末',comments='')
np.savetxt('score1.csv',arr,delimiter=',',fmt='%d',header='期中,期末',comments='')
#如果不适用分隔符 会认为数据是字符串 指定后数据为11,22 skiprpws跳过行 跳过第一行
# print(np.loadtxt('score.csv', delimiter=',', skiprows=1))
#指定dtype 全部读取 object
# print(np.loadtxt('score.csv',dtype='object', delimiter=','))
arr1 = np.loadtxt('score.csv',dtype='object', delimiter=',')
arr2 = np.loadtxt('score1.csv',dtype='object', delimiter=',',skiprows=1)
#垂直拼接
v_data = np.vstack((arr1,arr2))
print(v_data.shape)

NaN与inf

nan与inf介绍

nan:not a number 表示不是一个数字,属于浮点类。

  • 两个nan是不相等的

    • 该特性可以用来判断nan的个数
      • np.count_nonzero() 计算非零的个数
      • np.isnan() 判断数组元素是否是NaN,返回为bool值

inf:np.inf 表示正无穷,-np.inf表示负无穷,属于浮点类。

如何处理nan

  • 直接删除缺失值所在行,但是当数据量较小时,这样处理会有影响整体的数据。更优雅的做法,是当求和时,将np.nan处理为0;当求均值时,将np.nan处理为非nan的均值。
1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
arr = np.arange(16).reshape(4,4)
#nan为浮点数 inf也为浮点类型 不能直接变换
#取出6 变为nan
arr1 = arr.astype('float')
arr1[1,2] = np.nan
print(arr1[1, 2])
#两个np.nan是不相等的 nan与任何数值计算都是nan
# print(np.nan == np.nan)
#获取含有nan的行
ind = np.where(np.isnan(arr1))
print(ind)

np.random模块

  • np.random为我们提供了许多获取随机数的函数。其实是python内置random模块进行的封装。

  • np.random.seed

    用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed()值,则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。一般没有特殊要求不用设置。以下代码:

1
2
np.random.seed(1)
print(np.random.rand())

np.random.rand

生成一个值为[0,1)之间的数组,形状由参数指定,如果没有参数,那么将返回一个随机值。示例代码如下

1
data = np.random.rand() #生成一个0-1之间的随机数

np.random.randn

生成均值(μ)为0,标准差(σ)为1的标准正态分布的值。示例代码如下:

1
data = np.random.randn(2,3) #生成一个2行3列的数组,数组中的值都满足标准正太分布

np.random.randint

生成指定范围内的随机数,并且可以通过size参数指定维度。示例代码如下

1
data = np.random.randint(10,size=(3,5)) #生成值在0-10之间,3行5列的数组

np.random.choice

从一个列表或者数组中,随机进行采样。或者是从指定的区间中进行采样,采样个数可以通过参数指定

1
2
data = np.arange(100)
res = np.random.choice(data,size=(2,3)) #从data中随机采样,生成2行3列的数组

np.random.shuffle

把原来数组的元素的位置打乱。

1
2
a = np.arange(10)
np.random.shuffle(a) #将a的元素的位置都会进行随机更换

常用函数

方法 描述
sum 沿着轴向计算所有元素的累和,0长度的数组,累和为0
mean 数学平均,0长度的数组平均值为NaN
max,min 最大值和最小值
argmax,argmin 最大值和最小值的位置
std,var 标准差和方差
ptp 极值
cumsum 从0开始元素累积和
median 中值

一元函数

函数 描述
np.abs 绝对值
np.sqrt 开根
np.square 平方
np.exp 计算指数(e^x)
np.log,np.log10,np.log2,np.log1p 求以e为底,以10为低,以2为低,以(1+x)为底的对数
np.ceil 向上取整,比如5.1会变成6,-6.9会变成-6
np.floor 向下取整,比如5.9会变成5,-6.1会变成-7
np.rint,np.round 四舍六入五成偶
np.modf 将整数和小数分隔开来形成两个数组
np.isnan 判断是否是nan
np.isinf 判断是否是inf
np.cos,np.cosh,np.sin,np.sinh,np.tan,np.tanh 三角函数

二元函数

函数 描述
np.add 加法运算(即1+1=2),相当于+
np.subtract 减法运算(即3-2=1),相当于-
np.negative 负数运算(即-2),相当于加个负号
np.multiply 乘法运算(即23=6),相当于
np.divide 除法运算(即3/2=1.5),相当于/
np.floor_divide 取整运算,相当于//
np.mod 取余运算,相当于%
greater,greater_equal,less,less_equal,equal,not_equal >,>=,<,<=,=,!=的函数表达式
logical_and &的函数表达式
logical_or \

线性代数运算

函数 描述
det 计算矩阵行列式
eig 计算方阵的本征值和本征向量
inv 计算方阵的逆
qr 计算QR分解
svd 计算奇异值分解(SVD)
solve 解线性方程
lstsq 计算Ax=b的最小二乘解