numpy矩阵和数组

numpy:计算模块,主要有两种数据类型,数组和矩阵

特点:运算快

一:矩阵创建

导入模块

import numpy as np

创建一个3x2矩阵

行以分号;隔开

mat1 = np.mat("1 2;2 3;3 4")
print(mat1)

# 结果
[[1 2]
 [2 3]
 [3 4]]

矩阵相加

mat2 = np.mat("3 4;6 7;8 9")
print(f"{mat1 + mat2}")

# 结果
[[ 4  6]
 [ 8 10]
 [11 13]]

矩阵相乘

注意:前一个矩阵的列数和后一个矩阵的行数要相等

mat3 = np.mat("3 4; 5 6")
print(f"{mat1 * mat3}")

# 结果
[[13 16]
 [21 26]
 [29 36]]

矩阵转置

# 矩阵转置
print(mat1.T)

# 结果
[[1 2 3]
 [2 3 4]]

矩阵求逆

print(mat1.I)

# 结果
[[-1.83333333 -0.33333333  1.16666667]
 [ 1.33333333  0.33333333 -0.66666667]]

矩阵数乘

pirnt(f"{4 * mat1}")

# 结果
[[ 4  8]
 [ 8 12]
 [12 16]]

对应元素相乘

print(np.multiply(mat1,mat2))

# 结果
[[ 3  8]
 [12 21]
 [24 36]]

二:矩阵属性

矩阵结构

print(f"矩阵的结构{mat1.shape}")

# 结果
(3, 2)

矩阵元素个数

print(f"矩阵元素的个数{mat1.size}")

# 结果
6

矩阵元素类型

print(f"矩阵的元素类型{mat1.dtype}")

# 结果
int64

矩阵的维度

print(f"矩阵的维度{mat1.ndim}")

# 结果
2

三:数组的创建

数组的所有运算都是对应元素的运算

创建一维数组

arr1 = np.array([1,2,3,4])

# 结果
[1 2 3 4]

创建二维数组

arr2 = np.array([[1,2,3],[2,3,4],[3,4,5]])

# 结果
[[1 2 3]
 [2 3 4]
 [3 4 5]]

创建列向量类型的数组

arr3 = np.array([[1],[2],[3]])

# 结果
[[1]
 [2]
 [3]
 [4]]

四:数组的属性

arr1 = np.array([1,2,3,4])
arr2 = np.array([[1,2,3],[2,3,4],[3,4,5]])
arr3 = np.array([[1],[2],[3]])

数组结构

print(f"一维数组的结构{arr1.shape}")
print(f"二维数组的结构{arr2.shape}")
print(f"二维数组的结构{arr3.shape}")

# 结果
(4,)
(3, 3)
(4, 1)

数组元组的个数

print(f"一维数组元素的个数{arr1.size}")
print(f"二维数组元素的个数{arr2.size}")
print(f"二维数组元素的个数{arr3.size}")

# 结果
4
9
4

数组元素的类型

print(f"一维数组的元素类型{arr1.dtype}")
print(f"二维数组的元素类型{arr2.dtype}")
print(f"二维数组的元素类型{arr3.dtype}")

# 结果
int64
int64
int64

数组的维度

print(f"一维数组的维度{arr1.ndim}")
print(f"二维数组的维度{arr2.ndim}")
print(f"二维数组的维度{arr2.ndim}")

# 结果
1
2
2

数组的索引取值

  • 一维数组的切片
    与列表切片类似
# 将arr1数组倒序显示
print(arr1[::-1])

# 结果
[4 3 2 1]
  • 二维数组切片
    array[行数切片, 列数切片]
    适用:规则切片,即数字位于同一行同一列
# 切出arr2二维数组中四个角的元素
print(arr2[0::2,0::2])

# 结果
[[1 3]
 [3 5]]
  • 二维数组切片提高
    array[(col1,col2…),(row1,row2…)]
    注:col1与row1为一组,col2与row2为一组取出一个元素
    适用:不规则切片,随便取出一个数组中的某几个元素
# 取出arr2中所有的3
print(arr2[(0,1,2),(2,1,0)])

# 结果
[3 3 3]

数组布尔取值

注:尽量不要行列同时传入bool值,只在行的位置或列的位置传入。如果同时行列同时传入了bool值,就会像我们二维数组切片提高中的那样将行列都为Ture的坐标组成一个元组,然后再去取值。

mask = np.array([1,0,3],dtype=np.bool)  # 将一个列表转换成一个bool值数组
pirnt(mask)  # [ True False  True]
print(arr2[mask,::2])  

# 结果为:
[[1 3]
 [3 5]]

如果行列都为mask

print(arr2[mask,mask])

# 结果为:
[1 5]

五:特殊函数创建一维数组

  1. 通过arange函数创建数组
    np.arange(start,end,step)
    start为初始值,end为结束值,setp为步长
arr = np.arange(1,10,1)

# 结果
[1 2 3 4 5 6 7 8 9]
  1. 等差数列
    等差公式:an = a1 + (n-1)d
    np.linspace(start,end,n)
    参数介绍:
  • start为开始值,end为结束值,n为值的个数,程序会自动为我们按照开始值,结束值,n进行自动计算并返回一个等差数组。
  • endpoint=True:当endpoint为True时,表示等差数列,在start与stop之间插入n-2个值(适用于起点和终点不重合的情况,如线段)
  • endpoint=False:表示等差数列,在start于stop之间插入n-1个值,表示平均分成n份(适用于起点和终点重合的情况,如圆)
arr = np.linspace(2,8,4)  
print(arr)

# 结果
[2. 4. 6. 8.]
  1. 等比数列
    等比公式:an = a1 * q^(n-1)
    np.logspace(start,end,n,base)
    参数介绍:
  • start为base的初始指数索引值,end为base的结束指数索引值,n为值的个数,base为基数,默认base=10,可自行修改
arr = np.logspace(0,3,4)
print(arr)

# 结果
[   1.   10.  100. 1000.]
  1. 全一数组
    ones(row,col),参数row为行数,参数col为列数,行列必须放在一个元组中
arr = np.ones((3,4))
print(arr)

# 结果
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
  1. 全零数组
    参数格式与全一数组相似
arr = np.zeros((3,3))
print(arr)

# 结果
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
  1. 单位数组
    eye(n),n为要创建的单位数组的行列值
arr = np.eye(3)
print(arr)

# 结果
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
  1. 对角数组
    diag([item1,item2,item3,…]),item为对角的元素的值
arr = np.diag([1,2,3,4])
print(arr)

# 结果
[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]

六:随机数组

  1. random.random(size)
    创建size个在0~1之间的随机数,得到的是一维数组
arr = np.random.random(100)
print(arr)

# 结果
[0.83733231 0.74140504 0.51916379 0.54494728 0.22548001 0.62170341 0.38315409 0.73351002 0.53539849 0.05316726]
  1. random.rand(size)
    创建size个0~1个服从均匀分布的随机数,得到的是一维数组
arr = np.random.rand(100)
print(arr)

# 结果
[0.48635214 0.5878932  0.54523463 0.88037286 0.0768012  0.23856749 0.88212262 0.98236016 0.29002847 0.45952624]
  1. random.randn
    创建正态分布数组
arr = np.random.randn(100)
print(arr)

# 结果
[ 0.07046502 -1.41616446 -0.75543114 -0.67044859 -0.046139    1.87599295 -1.15266343 -1.21954818 -0.30111463  0.8468181 ]
  1. random.randint(min,max,size)
    随机生成[min,max]范围内的值,size为一个值时,表示一维数组,为一个列表时,表示二维数组。
arr = np.random.randint(1,10,size=4)
print(arr)

# 结果
[4 1 5 2]
arr = np.random.randint(1,10,size=[3,4])
print(arr)

# 结果
[[8 6 2 1]
 [1 9 2 1]
 [6 9 4 5]]

七:数组形态变换

  1. 重置数组结构
    将一维数组变为二维数组
    注:要保证一维数组和二维数组元素个数一致
arr1 = np.arange(12)
arr2 = arr1.reshape((3,4))
print(arr2)

# 结果
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
  1. 展平方法一:二维变一维
arr3 = arr2.ravel()
print(arr3)

# 结果
[ 0  1  2  3  4  5  6  7  8  9 10 11]
  1. 展平方法二:二维变一维
    C:表示按行展平;F表示按列展平
arr4 = arr2.flatten("C")
print(arr4)

# 结果
[ 0  1  2  3  4  5  6  7  8  9 10 11]
arr5 = arr2.flatten("F")
print(arr5)

# 结果
[ 0  4  8  1  5  9  2  6 10  3  7 11]
  1. 堆叠方法
    hstack:横向堆叠,要保证行数一致
    vstack:纵向对叠,要保证列数一致,可通过vstack将两个一维数组变为二维数组
arr1 = np.zeros((3,4))
arr2 = np.ones((3,4))
arr6 = np.hstack((arr1, arr2))
print(arr6)

# 结果
[[1. 1. 1. 1. 0. 0. 0. 0.]
 [1. 1. 1. 1. 0. 0. 0. 0.]
 [1. 1. 1. 1. 0. 0. 0. 0.]]

arr7 = np.vstack((arr1, arr2))
print(arr7)

# 结果
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
  1. 数组合并
    方法:concatenate
    axis:表示轴。一维数组中,只有横向轴,用axis=0表示;二维数组中,有横向和纵向两根轴,axis=0表示纵向轴,axis=1表示横向轴
arr8 = np.concatenate((arr1, arr2), axis=0)
print(arr8)

# 结果
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
  1. concatenate 与 hstack、vstack区别
    它们两个方法的主要区别在于concatenate引进了轴的概念,所以在拼接或者说合并时,必须要满足轴的存在条件以及存在方向。这种区别可在一维数组上得到体现,一位数组中只存在axis=0这一根轴,所以当我们指定参数时,会抛出错误。
np.concatenate((arr1,arr2),axis=1)
# 当axis=1时,程序会抛出无axis=1轴错误。
  1. 数组分割
    hsplit(array,num):横向分割,均分,num为均分后数组的个数,num的值必须为数组列数的约数
    hsplit(array,[item1,item2,item3]):横向分割,指定列数分割,即按照 0item1,item1item2,item2item3,item3最后一列 进行切割。如果切割数超出了数组范围,则返回一个空列表。
arr9 = np.hsplit(arr6, 4)
print(arr9)

# 结果
[array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[0., 0.],
       [0., 0.],
       [0., 0.]]), array([[0., 0.],
       [0., 0.],
       [0., 0.]])]

arr10 = arrnp.hsplit(arr6, [2,4,7,9])
print(arr10)

# 结果
[array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]]), array([[0.],
       [0.],
       [0.]]), array([], shape=(3, 0), dtype=float64)]

vsplit(array,num):使用方法与hsplit类似

arr11 = np.vsplit(arr7, 3)
print(arr11)

# 结果
[array([[1., 1., 1., 1.],
       [1., 1., 1., 1.]]), array([[1., 1., 1., 1.],
       [0., 0., 0., 0.]]), array([[0., 0., 0., 0.],
       [0., 0., 0., 0.]])]

arr12 = np.vsplit(arr, [2,4,7,9])
print(arr12)

# 结果
[array([[1., 1., 1., 1.],
       [1., 1., 1., 1.]]), array([[1., 1., 1., 1.],
       [0., 0., 0., 0.]]), array([[0., 0., 0., 0.],
       [0., 0., 0., 0.]]), array([], shape=(0, 4), dtype=float64)]

split(array,num,axis)

axis表示轴,axis=0时表示纵向切割,axis=1表示横向切割

arr13 = np.split(arr,4,axis=0)
print(arr13)

# 结果
[array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[1., 1.],
       [1., 1.],
       [1., 1.]]), array([[0., 0.],
       [0., 0.],
       [0., 0.]]), array([[0., 0.],
       [0., 0.],
       [0., 0.]])]

八:数组运算

arr1 = np.array([1,2,3,4])
arr2 = np.diag([1,2,3,4])
arr3 = np.arange(16).rshape((4,4))
  1. 普通运算

数组的四则运算是对于数组的每个元素进行相应的计算,运算包括 加减乘除,取整,取余等

# 乘法
print(arr2 * arr3)

# 结果
[[ 0  0  0  0]
 [ 0 10  0  0]
 [ 0  0 30  0]
 [ 0  0  0 60]]
 
 # 这里是一个一维数组和二维数组相乘,底层用到了广播运算,我们会在接来下降到
 print(arr1 * arr2)
 
 # 结果
[[ 1  0  0  0]
 [ 0  4  0  0]
 [ 0  0  9  0]
 [ 0  0  0 16]]
  1. 比较运算
    对数组和数组或数组和值进行比较,符合条件返回true,不符合条件返回false。如果是数组和数组比较,则比较对应位置上的元素,并返回bool值数组。如果是数组和值比较,则把数组的每一个位置的元素都与值进行比较,并返回bool值数组。
mask = arr3 > 8
print(mask)

# 结果
[[False False False False]
 [False False False False]
 [False  True  True  True]
 [ True  True  True  True]]

# 例:找出arr3中大于8的元素
print(arr3[mask])

# 结果
# 将所有对应位置为true的值以一维数组的格式返回
[ 9 10 11 12 13 14 15]
  1. 逻辑运算
    将一个bool数组转换成一个bool值
    逻辑与:
    当mask中的所有元素均为true时,就返回true,否则返回false
np.all(mask)

逻辑或:

当mask中的所有元素均为false时,就返回false,否则返回true

np.any(mask)
  1. 数组广播运算
    广播运算:对一列或一行数组在进行运算时进行复制,使他具有与它相运算数组相同的结构,从而可以进行运算。
    以上普通运算一维数组与二维数组相乘,以及比较运算中数组与值的比较都是经过广播运算后再进行相乘或比较的。
    注:若为数组和一行(列)数组进行运算,必须满足数组的列(行)和一行(列)数组的个数相等。只有一行(列)数组能够进行广播运算。
  2. 特殊方法
  • 排序
    sort
    在原数组上进行排序,如果是多维数组,则可以使用axis参数来指定排序的方向。axis默认为-1,即沿着最后一个轴进行排序。可使用order参数指定相关算法对数组进行排序。
# 一维数组排序
arr4 = np.array([1,3,5,2,4])
arr4.sort()
print(arr4)

# 结果
[1 2 3 4 5]

# 二维数组排序
# 按axis=0,即给每一列排序
arr5 = np.array([[12,2,10,9],[2,90,25,1]])
arr.sort(axis=0)
print(arr5)

# 结果
[[12  2 10  1]
 [20 90 25  9]]

argsort

返回的是排序后的索引,即先排序,返回将排序后数字的原来的索引。不会修改原数组。如果是二维数组,可用axis参数指定排序的方法。可使用order参数指定相关算法对数组进行排序。

# 一维数组排序
arr6 = np.array([1,3,5,2,4])
arr7 = arr.argsort()
print(arr7)

# 结果
[0 3 1 4 2]

# 二维数组排序
arr8 = np.array([[12,2,10,9],[2,90,25,1]])
arr9 = arr8.argsort(axis=0)
print(arr9)

# 结果
[[0 0 0 1]
 [1 1 1 0]]
  • 去重
    np.unique(array,None)
    当数组是二维数组数组时,去重后返回的是一个一维数组
    axis参数:
    当axis为None时,先展平之后再进行去重,然后进行排序。当axis为0(1)时,则对纵轴(横轴)进行切割并去重,即将一每行(列)视为一个值,当某一行(列)中的元素与另一行(列)元素全部相同时,则进行去重操作。去重后会根据行(列)的第一个值进行排序,如果第一个行(列)值相等,则再去比较第二个,以此类推。
# 一维数组
arr10 = np.array([1,4,6,3,4,7,1])
print(np.unique(arr10))

# 结果
[1 3 4 6 7]
# 二维数组
arr11 = np.array([[1,4,4,6,1],[2,3,3,2,1],[1,4,4,6,1]])
print(np.unique(arr11))
print(np.unique(arr11,axis=0))
print(np.unique(arr11,axis=1))

# 结果
[1 2 3 4]

[[1 4 4 6 1]
 [2 3 3 2 1]]
 
[[1 1 4 6]
 [1 2 3 2]
 [1 1 4 6]]