numpy常用操作

1 numpy库

在此只简单介绍numpy一些常用操作,具体详细内容请转到 numpy中文网

​ numpy是Python支持科学计算的重要扩展库,也是数据分析领域必备的基础包,提供众多功能。

​ numpy安装,在cmd中输入:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy

2 数组对象 ndarray

​ 标准的Python中用list(列表)保存值,可以当作数组使用,但因为列表中的元素可以是任何对象,所以浪费了CPU运算时间和内存。

​ numpy提供了一个具有矢量算术运算能力和复杂广播能力的ndarray数组对象。为了保证快速运算且节省空间的优良性能,ndarray对象中许多操作采用代码在本地编译执行的方式。

​ numpy数组与Python列表的主要区别如下:

  • numpy数组具有固定大小,更改numpy数组的大小将创建一个新数组并删除原来的numpy数组。而Python列表对象包含的元素数目是可以动态增长的。
  • numpy数组中的元素通常具有相同的数据类型,因此在内存中占据的存储空间相同。而Python列表元素可以是不同类型的数据。
  • numpy数组可以实现高效快速的矢量算术运算。与Python列表相比,numpy数组无需使用循环语句,可以完成类似Matlab中的矢量运算,需要编写的代码更少,在处理多维度大规模数据时快速且节省空间。
  • 越来越多基于Python的数学运算和科学计算软件包使用numpy数组参与计算过程。虽然这些工具通常支持Python列表作为参数,但在处理之前会将Python列表转换为numpy数组参与计算,通常输出结果也是numpy数组。

2.1 数组对象的创建

​ ndarray对象是numpy模块的基础对象,是用于存放同类型元素的多维数组。可以使用整数索引获取数组中的元素,序号从0开始。在numpy中,ndarray对象的维度( dimensions )称为轴(axis ),轴的个数叫做秩( rank )。一维数组的秩为1,二维数组的秩为2,以此类推。二维数组相当于两个一维数组,其中第一维度的每个元素又是一个一维数组。Python中关于ndarray对象的许多计算方法都是基于axis进行。当axis=0,表示沿着第0轴进行操作,即对每一列进行操作;当axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

2.1.1 利用array函数创建ndarray对象

​ 创建一个ndarray对象可以使用numpy的array函数,格式如下:

numpy.array(object, dtype = None, copy =True, order = None, subok = False, ndmin = 0)

#参数object:表示数组或嵌套的数列;
#可选参数dtype:表示数组元素的数据类型;
#可选参数copy:指出对象是否需要复制;
#参数order:描述创建数组的样式,C为行方向,F为列方向,默认值A表示任意方向;
#参数subok:默认返回一个与基类类型一致的数组;
#参数ndmin:指定生成数组的最小维度。
import numpy as np

np.array([1,2,3,4,5])  #将列表转换为数组

np.array((1,2,3,4,5))  #将元组转换为数组

np.array((1,2,3,4,5))  #将元组转换为数组

mat = [[1., 2., 3.], [4., 5., 6.]]   # 二维数组
np.array(mat)

2.1.2 np.ones()和np.zeros()函数

np.zeros((m,n),dtype)函数用于创建一个m行n列的全0数组,其中参数dtype指定数组类型。

# 创建3行4列的全0数组(矩阵)
np.zeros((3,4))

np.ones((m,n),dtype)函数用于创建一个m行n列的全1数组,其中参数dtype指定数组类型。

# 创建一个2行3列的全1数组(矩阵)
np.ones((2,3),dtype=np.int)

注意,np.ones()和np.zeros()函数中第一个参数是元组类型,用来指定数组的大小

2.1.3 np.random.rand()函数

np.random.rand()函数创建一个指定形状的随机数组,数组元素是服从“0~1”均匀分布的随机样本,取值范围是[0,1),不包括1。

# 生成包含3个元素的
np.random.rand(3)
# 生成三行四列的
np.random.rand(3, 4)

2.1.4 np.arange()函数

np.arange()函数类似Python自带的range函数,用于创建一个等差序列的ndarray数组。

np.arange(10)

np.arange(10,20,2)

2.1.5 np.linspace()函数

np.linspace(x,y,n)函数用于创建间隔均匀的数值序列,生成一个以x为起始点,以y为终止点,等分成n个元素的等差数组。

np.linspace(1,10,5)    #等差数组,包含5个数   array([ 1.  ,  3.25,  5.5 ,  7.75, 10.  ])

np.linspace(1,10,5,endpoint=False)  #不包含终点  array([1. , 2.8, 4.6, 6.4, 8.2])

2.1.6 np.empty()函数

np.empty((m,n),dtype)函数创建一个m行n列的数组,参数dtype指定数组元素的数据类型。此方法生成的数组元素不一定为空,而是随机产生的数据。

np.empty((3,4))  ##返回指定维度的数组,元素值是接近于0的随机数

​ 若没有指定数据类型,该方法返回的数据类型为默认类型numpy.float64,这时生成的数组元素不可能为空。

2.2 ndarray对象常用属性

ndarray对象常用属性ndim返回正整数表示的数组维度个数,即数组的秩;shape属性返回数组维度,返回值为N个正整数组成的元组类型,元组的每个元素对应各维度的大小,元组的长度是秩,即维度个数或者ndim属性;dtype属性返回数组元素的数据类型,每个ndarray对象只有一种dtype类型;size属性返回数组元素总个数,返回值为shape属性中元组元素的乘积。

​ 通过序列型对象创建ndarray数组data , ndim属性返回整数“1”表示这是一维数组,shape属性返回数组的维度个数和各维度元素的数量,即只有一维,该维度元素数量为“6”,dtype属性表明data数组元素的类型为"int64”,size属性表明data数组各维度元素总数为“6”。

# 一维数组
arr = [1, 2, 3, 4, 5, 6]
data = np.array(arr)
print(data)

print('维度个数', data.ndim)
print('各维度大小: ', data.shape)
print('数据类型: ', data.dtype)
print('数组元素总个数:', data.size)



"""
[1 2 3 4 5 6]
维度个数 1
各维度大小:  (6,)
数据类型:  int64
数组元素总个数: 6
"""
# 二维数组
l = [[1., 2., 3.], [4., 5., 6.]]
data = np.array(l)
print(data)

print('维度个数', data.ndim)
print('各维度大小: ', data.shape)
print('数据类型: ', data.dtype)

"""
[[1. 2. 3.]
 [4. 5. 6.]]
维度个数 2
各维度大小:  (2, 3)
数据类型:  float64
"""
# 三维数组
l = [
        [
            [1, 2], 
            [3, 4]
        ], 
        [
            [5, 6], 
            [7, 8]
        ]
]
data = np.array(l)
print(data)

print('维度个数', data.ndim)
print('各维度大小: ', data.shape)
print('数据类型: ', data.dtype)


"""
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]
维度个数 3
各维度大小:  (2, 2, 2)
数据类型:  int32
"""

2.3 ndarray常用操作

2.3.1 改变数组形状

numpy模块在修改数组形状时,可以使用reshape()函数,语法格式如下:

np.reshape(arr, newshape, order='C')

arr.reshape(newshape,oder='C')

#参数arr表示需要求修改形状的数组;
#参数newshape为整数或由整数元素构成的元组,表示修改后的数组形状,要求新数组的形状应当与数组元素数量及形状兼容,否则抛出异常﹔
#参数order默认取值为“"C'”,表示按列读取数组元素,若order='F',表示按行读取数据,若order='A',表示按原顺序读取数据。
arr2=np.array(range(10))
print(arr2)
# [0 1 2 3 4 5 6 7 8 9]


arr2 = arr2.reshape((5,2))  # np.reshape(arr2,(5,2))
"""
[[0 1]
 [2 3]
 [4 5]
 [6 7]
 [8 9]]
"""


arr2 = arr2.reshape((5,2),order='F') # np.reshape(arr2,(5,2),order="F")
"""
[[0 5]
 [1 6]
 [2 7]
 [3 8]
 [4 9]]
"""

np.resize()函数对数组形状进行原地修改,并且根据需要补充或丢弃部分元素。

np.resize(arr2,(1,15))
# array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]])

np.resize(arr2,(3,4))
"""
array([[0, 1, 2, 3],
      [4, 5, 6, 7],
      [8, 9, 0, 1]])
"""

此外,还可以使用数组的shape属性直接原地修改数组大小

arr2.shape=2,5
arr2

"""
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
"""

2.3.2 改变数组元素类型

astype()方法用于改变数组元素的数据类型。在使用astype的时候,即使指定的数据类型与原始数组相同,系统也会创建一个新数组。

print(arr2.dtype)	# int64

arr3 = arr2.astype(float)
print(arr3.dtype)	# float64

2.3.3 数组降维

ndarray.flatten()方法用于数组降维操作,将二维或者三维数组快速扁平化,返回一个一维数组。默认情况下按照行方向降维。

arr3 = np.array([[1,2], [3,4],[5,6]])
print(arr3)

"""
[[1 2]
 [3 4]
 [5 6]]
"""

arr3.flatten()  # 默认按行方向降维 [1 2 3 4 5 6]
arr3.flatten('F') # 按列方向降维 [1 3 5 2 4 6]


2.3.4 数组转置

np.transpose()函数用于调换数组的索引值,对于二维数组,相当于求数组的转置对象。ndarray.T属性也可实现线性代数中矩阵转置功能。

data = np.arange(15).reshape(3, 5)
print(data)

"""
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
"""

print(data.T)
print(np.transpose(data))
"""
[[ 0  5 10]
 [ 1  6 11]
 [ 2  7 12]
 [ 3  8 13]
 [ 4  9 14]]
"""

​ Numpy函数np.swapaxes(a,x,y)等价于ndarray对象的a.swapaxes(x,y)方法,用于将n维数组中x、y两个维度的数据调换。

print(np.swapaxs(data, 0, 1))	# 将0维与1维数据调换,二维数组中相当于转置

"""
[[ 0  5 10]
 [ 1  6 11]
 [ 2  7 12]
 [ 3  8 13]
 [ 4  9 14]]
"""

2.3.5 数组对象合并

​ 数组合并用于多个数组间的操作,numpy的hstack()vstack()函数分别用于沿着水平和垂直方向将多个数组合并在一起。

​ 水平方向的数据合并操作将ndarray对象构成的元组作为参数,传递给hstack()函数。

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

​ 垂直方向的数据合并操作将ndarray对象构成的元组作为参数,传递给vstack()函数。

np.vstack((arr1,arr2))

"""
array([[1, 2, 3],
       [4, 5, 6]])
"""

​ numpy中重要的concatenate()函数提供了类似的数据合并功能,其中参数axis指定数据合并的方向或维度。参数axis默认值为0,表示按照垂直方向进行数据合并;参数axis=1表示按照水平方向进行数据合并。

2.3.6索引和切片

​ ndarray对象的索引通常用于获取数组元素,ndarray对象的切片通常获取数组中多个元素组成的数据片段。ndarray对象的基本索引和切片得到的结果都是原始数组的视图,修改视图也会修改原始数组。

​ ndarray对象的一维数组和python列表结构类似,以单个索引值的方式访问ndarray对象的一维数组会返回对应的标量元素值。

data = np.array([1, 2, 3, 4, 5, 6])   # 一维数组索引
print(data)		# [1 2 3 4 5 6]
print(data[0])	# 1
print(data[-1]) # 6
print(data[3:]) # [4,5,6]

​ ndarray对象的二维数组可以看作一维数组的嵌套形式,当ndarray对象以一维数组的索引方式访问一个二维数组时,获取的元素就是一个一维数组,然后可以继续按照访问一维数组的方式获取二维数组中的某个标量。

# 多维数组索引
data = np.arange(9).reshape(3, 3)
print(data)
"""
[[0 1 2]
 [3 4 5]
 [6 7 8]]
"""

print(data[2])
"""
[6 7 8]
"""

print(data[2][0])  # 6
print(data[2, 0])  # 6

print(data[:2, 1:])  # 0行-1行 1列-2列
"""
[[1 2]
 [4 5]]
"""

​ ndarray对象的布尔值索引又称条件索引,是指一个由布尔值组成的数组可以作为另一个数组的索引,返回的数据为新数组中True值对应位置的元素。通过布尔运算(如∶比较运算符)来获取符合指定条件的元素组成的数组。

# 条件索引
# 找出数据中大于4的数据
is_gt = data > 4

print(is_gt)
"""
[[False False False]
 [False False  True]
 [ True  True  True]]
"""

print(data[is_gt])
"""
[5 6 7 8]
"""

# 简写
print(data[data > 4])

# 找出数据中大于4的偶数
print(data[data > 4 & (data % 2) == 0])

2.4 numpy常用函数

2.4.1 常用统计函数

​ 几乎所有numpy统计函数在关于二维数组的运算时都需要注意参数axis的取值。对二维数组而言,如果未设置参数axis,那么针对所有元素进行操作;如果axis=o,表示按照列或垂直方向,即沿着纵轴进行操作;如果axis=1,表示按照行或水平方向,即沿着横轴进行操作。

在这里插入图片描述

import numpy as np

data = np.arange(10).reshape(5, 2)
print(data)

"""
[[0 1]
 [2 3]
 [4 5]
 [6 7]
 [8 9]]
"""
print(np.mean(data))
print(np.mean(data, axis=0))
print(np.mean(data, axis=1))

"""
4.5
[4. 5.]
[0.5 2.5 4.5 6.5 8.5]
"""
print(np.sum(data))
print(np.sum(data, axis=0))
print(np.sum(data, axis=1))

"""
45
[20 25]
[ 1  5  9 13 17]
"""
print(np.max(data))
print(np.max(data, axis=0))
print(np.max(data, axis=1))

"""
9
[8 9]
[1 3 5 7 9]
"""
print(np.std(data))
print(np.var(data))

"""
2.8722813232690143
8.25
"""
print(np.argmax(data))
print(np.argmax(data, axis=0))
print(np.argmax(data, axis=1))

"""
9
[4 4]
[1 1 1 1 1]
"""
print(np.cumsum(data))
print(np.cumsum(data, axis=0))
print(np.cumsum(data, axis=1))

"""
[ 0  1  3  6 10 15 21 28 36 45]
[[ 0  1]
 [ 2  4]
 [ 6  9]
 [12 16]
 [20 25]]
[[ 0  1]
 [ 2  5]
 [ 4  9]
 [ 6 13]
 [ 8 17]]
"""
print("中位数:",np.median(data))  #返回中位数
print("最小值的索引:",np.argmin(data))	#返回最小值的索引
print("最大值的索引:",np.argmax(data))	#返回最大值的索引


"""
中位数: 4.5
最小值的索引: 0
最大值的索引: 9
"""
print("加权平均数(无权值参数)",np.average(data)) 
print("加权平均数(设置权值)",np.average([1,2,3,4],weights = [4,3,2,1]))

"""
加权平均数(无权值参数) 4.5
加权平均数(设置权值) 2.0
"""
data=np.swapaxes(data, 0, 1)
print(data)
print(np.argsort(data,axis = 0)) #按列从小到大排序,输出对应索引
print(np.argsort(data,axis = 1))#按行从小到大排序,输出对应索引

"""
[[0 2 4 6 8]
 [1 3 5 7 9]]
 
 [[0 0 0 0 0]
 [1 1 1 1 1]]
 
[[0 1 2 3 4]
 [0 1 2 3 4]]
"""

2.4.2 all(),any(),unique()函数

np.all()函数对所有元素进行与操作,用于判断是否所有元素都满足条件。只有所有元素取值为True,该函数的返回结果才为True。

np. any()函数对所有元素进行或操作,用于判断是否至少一个元素满足条件。只要任意一个元素取值为True,该函数的返回结果即为True。

np.unique()函数返回数组中所有不同的值,并按照从小到大排序。该函数用于去除数组中的重复数据,并返回排序后的结果。np.unique()函数的可选参数return_index=True时,该函数返回新数组中每个元素在原数组中第一次出现的索引值,因此元素个数与新数组中元素个数一样。可选参数return_inverse=True时,该函数返回原数组中每个元素在新数组中出现的索引值,因此元素个数与原数组中元素个数一样。

print(np.all(data > 5))
print(np.any(data > 5))
A =np.array([1, 2, 5, 3, 4, 3, 2]) 
print ("原数组:", A)
# a = np.unique(A)  #返回任意的一个参数值
# print ("新数组:", a)  

# a, s = np.unique(A, return_index=True) #返回任意的两个参数值
# print ("新数组:",a) 
# print ("return_index:",s) 
 
#返回全部三个参数值
a, s, p = np.unique(A, return_index=True, return_inverse=True)
print ("新数组:",a)  
print ("return_index", s) 
print ("return_inverse", p) 

"""
原数组: [1 2 5 3 4 3 2]
新数组: [1 2 3 4 5]
return_index [0 1 3 4 2]
return_inverse [0 1 4 2 3 2 1]
"""

2.5 数组运算

2.5.1 数组的向量化

​ numpy数组可以使用简单的数组表达式完成多种数据操作任务,而无需使用大量循环语句。这种使用数组表达式替代循环操作的方法,称为向量化。通过向量化操作,可以一次性地在一个复杂对象上操作,或者将函数应用于一个复杂对象,避免了在对象的单个元素上使用复杂循环语句完成操作任务,达到代码更紧凑、执行速度更快的代码实现效果。

​ 实际上,numpy中关于ndarray对象的循环操作是通过高效优化的C代码实现,执行速度远快于纯python。通常,向量化的数组操作比纯python的等价实现在速度上至少快1-2个数量级。这为实现高效的数值计算奠定了基础。

a = np.arange(100000, dtype=float)
b = np.arange(100000, 0, -1, dtype=float)

# 未使用向量化
import time

begin = time.time()
results = []
for i, j in zip(a, b):
    results.append(i * j)
end = time.time()
print('运行时间:', end - begin)

# 使用向量化
begin = time.time()
results = a * b
end = time.time()
print('运行时间:', end - begin)

2.5.2 numpy的广播机制

​ numpy广播机制是实现向量化计算的有效方式。当需要处理的数组维度大小不一致时,numpy广播机制提供了不同形状的数组仍然能够计算的实现机制。

作为多维向量的组合,数组(或者称向量)计算大多在相同形状的数组之间进行,要求被处理的数组维度以及每个维度大小是相等的,这时的数组操作应用在元素上,即数组元素—一对应的操作。但是,许多计算可能涉及一个维度与其他所有维度之间的操作,此时被操作的数组大小不同。当两个形状并不相同的数组参与运算时,可以使用扩展数组的方式实现相加、相减、相乘等操作,这种机制称为广播( broadcasting ) 。numpy采用广播机制来实现不同形状的数组间运算。

​ 两个numpy数组的相加、相减以及相乘都是对应元素的操作。如果两个数组x和y形状相同,即满足a.shape == b.shape,那么x*y的运算结果是数组x与y数组对应元素相乘。这里要求两个数组维数相同,且各维度的长度相同。

x = np.array([[2,2,3],[1,2,3]])
y = np.array([[1,1,3],[2,2,4]])
print(x*y)  #numpy当中的数组相乘是对应元素的乘积,与线性代数当中的矩阵相乘不一样

"""
[[ 2  2  9]
 [ 2  4 12]]
"""

​ 当参与运算的两个数组形状不一致时,如果数组形状符合广播机制的要求,numpy将自动触发广播机制。通俗地说,首先将两个数组的维度大小右对齐,然后比较对应维度上的数值,如果数值相等或其中有一个为1或者为空,那么能够进行广播运算,并且输出维度的大小取数值大的维度值。否则不能讲行数组运算。

# 报错
np.arange(6).reshape((2, 3)) + np.arange(10).reshape(2,5)
np.arange(6).reshape((3, 2))+ np.arange(10).reshape(5,2)
np.arange(5) + np.arange(10).reshape(5,2)#一维数组长度不等于二维数组列

​ 广播机制遵循的规则︰第一,所有输入数组都向其中shape最长的数组看齐,shape中不足的部分通过在小维度数组的前面添加长度为1的轴补齐;第二,输出数组的shape是输入数组shape中各个轴上的最大值;第三,当输入数组的某个轴长度为1时,沿着此轴运算时都用该轴上的第一组值。

np.arange(3) + 5  # 一维数组与数字的计算,向量与标量的计算
np.ones((3, 3)) + np.arange(3)
np.arange(3).reshape((3, 1)) + np.arange(3)

2.5.3 ufunc通用函数

ufunc ( universal function )函数意为“通用函数”,是一种能够对数组中每个元素进行操作的函数。ufunc函数对输入数组进行基于元素级别的运算,输出结果为numpy数组。numpy中许多ufunc内置函数的底层代码是基于C语言实现的,因此对一个数组进行重复运算时,使用ufunc函数的计算速度比使用math标准库函数要快很多。但是,在对单个数值进行运算时,python提供的运算要比numpy执行效率高。

这里仅介绍几个常用的ufunc函数:

  • ceil()函数对数组元素向上取整,返回向上最接近该元素的整数;
  • floor()函数对数组元素向下取整,返回向下最接近该元素的整数;
  • rint()函数对数组元素进行四舍五入,返回最接近的整数;
  • isnan()函数用于判断数组元素是否为NaN(Not a Number)。
  • multiply()函数用于元素相乘,等同于数组的“*”操作,需要注意该操作与数学中的矩阵乘法不同;
  • divide()函数用于元素相除,等同于数组的“/”操作。
arr = np.random.rand(2,3)
print(arr)

"""
[[0.71839548 0.20036517 0.89502509]
 [0.93971801 0.46314581 0.88237713]]
"""

print(np.ceil(arr))
print(np.floor(arr))
print(np.rint(arr))
print(np.isnan(arr))

"""
[[1. 1. 1.]
 [1. 1. 1.]]
 
[[0. 0. 0.]
 [0. 0. 0.]]
 
[[1. 0. 1.]
 [1. 0. 1.]]
 
[[False False False]
 [False False False]]
"""
np.multiply(np.arange(3), 5)
np.arange(3) * 5

np.divide(np.arange(3), 5)
np.arange(3) / 5

3 numpy矩阵

3.1 矩阵简介

numpy中包含一个矩阵库numpy.matlib,该模块的函数返回一个矩阵,而不是ndarray对象。一个m*n的矩阵是一个由m行(row ) n列( column)元素排列而成的矩形阵列。

​ numpy函数库中的矩阵matrix和数组array都可以用于处理行列表示的数值型元素。它们在形式上很相似,同时二者存在着一定区别和联系。

  • 数组array是numpy模块的基础,矩阵matrix可以看作数组的特殊形式;

  • 矩阵是数学上的概念,而数组是一种数据存储方式;

  • 矩阵matrix只能包含数字,而数组array可以是任意类型的数据;

  • 矩阵matrix只能表示二维数据,而数组array可以表示任意维度数据,或者说matrix相当于二维数组。当matrix某维度为1时,如向量(m,1)可称为列向量,而向量(1,n)为行向量;

  • 矩阵matrix的优势是使用相对简单的运算符号,如矩阵相乘用符号*,但是数组array相乘使用dot()方法。array的优势是不仅仅表示二维,还能表示三维等更多维度的数据。

    实际上,matrix是array的分支,matrix和array在很多时候都是通用的。如果二者可以通用的情况下,官方建议尽量选择array,因为array更灵活,速度更快,很多人也把二维的array翻译成矩阵。在实际应用中,使用numpy数组的情况更常见;但是当应用对矩阵运算有要求时,定义和使用numpv矩阵同样便捷

3.2 生成矩阵

import numpy as np

x=np.matrix([[1,2,3],[4,5,6]])
y=np.matrix([1,2,3,4,5,6])
print(x,y,sep='\n\n')

"""
[[1 2 3]
 [4 5 6]]

[[1 2 3 4 5 6]]
"""
print(x[1,1],sep='\n\n')  #返回行下标和列下标都为1的元素
np.matrix('1 3;5 7')

"""
matrix([[1, 3],
        [5, 7]])
"""
np.mat(np.eye(2,2,dtype=int)) #2*2对角矩阵

"""
matrix([[1, 0],
        [0, 1]])
"""
np.mat(np.random.randint(2,8,size=(2,5)))  #元素取值为2-8的随机整数矩阵

"""
matrix([[7, 3, 2, 6, 3],
        [3, 4, 6, 4, 6]])
"""

​ 显然,matrix)函数与array)函数生成矩阵所需的数据格式存在差别。matrix()函数处理的数据可以是分号(;)分割的字符串,也可以是逗号(,)分割的列表类型,而array()函数处理的数据大多是逗号(,)分割的列表类型。

3.3 矩阵特征

​ numpy扩展库中的max()、min()、sum()、mean()等方法均支持矩阵操作。在大多数矩阵方法中,可以使用参数axis指定计算方向。axis=1表示水平方向的计算;axis=0表示垂直方向的计算;如果不指定axis参数,则对矩阵平铺后的所有元素进行操作。

print(x,end='\n===\n')
print('所有元素平均值:',x.mean(),end='\n===\n')
print('垂直方向平均值:',x.mean(axis=0))
print('形状',x.mean(axis=0).shape,end='\n===\n')
print('水平方向平均值:',x.mean(axis=1))
print('形状',x.mean(axis=1).shape)


"""
[[1 2 3]
 [4 5 6]]
===
所有元素平均值: 3.5
===
垂直方向平均值: [[2.5 3.5 4.5]]
形状 (1, 3)
===
水平方向平均值: [[2.]
 [5.]]
形状 (2, 1)
"""
print('所有元素之和:',x.sum(),)
print('横向最大值:',x.max(axis=1),end='\n===\n')
print('横向最大值的下标:',x.argmax(axis=1),end='\n===\n')
print('对角线元素:',x.diagonal(),end='\n===\n')
print('非零元素行、列下标:',x.nonzero())

"""
所有元素之和: 21
横向最大值: [[3]
 [6]]
===
横向最大值的下标: [[2]
 [2]]
===
对角线元素: [[1 5]]
===
非零元素行、列下标: (array([0, 0, 0, 1, 1, 1]), array([0, 1, 2, 0, 1, 2]))
"""

3.4矩阵常用操作

# 矩阵转置
print(x.T,y.T,sep='\n\n')


"""
[[1 4]
 [2 5]
 [3 6]]

[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]
"""
# 矩阵相乘
x=np.matrix([[1,2,3],[4,5,6]])
y=np.matrix([[1,2],[3,4],[5,6]])
print(x*y)

"""
[[22 28]
 [49 64]]
"""
# 方差、协方差、标准差

A=np.matrix([1,2,3,4])
B=np.matrix([4,3,2,1])

print("单变量协方差、方差:",np.cov(A))  
print("两变量协方差:",np.cov(A,B))
print("单变量标准差:",np.std(A))
print("单变量行元素标准差:",np.std(A,axis=1))

"""
单变量协方差、方差: 1.6666666666666665
两变量协方差: [[ 1.66666667 -1.66666667]
 [-1.66666667  1.66666667]]
单变量标准差: 1.118033988749895
单变量行元素标准差: [[1.11803399]]
"""
# 特征值、特征向量
A=np.matrix([[1,-3,3],[3,-5,3],[6,-6,4]])
e,v=np.linalg.eig(A)
print("特征值:",e,sep='\n')
print("特征向量:",v,sep="\n")
print("矩阵与特征向量的乘积:",np.dot(A,v))
print("特征值与特征向量的乘积:",e*v)
print("验证二者是否相等:",np.isclose(np.dot(A,v),e*v))

"""
特征值:
[ 4.+0.00000000e+00j -2.+1.10465796e-15j -2.-1.10465796e-15j]
特征向量:
[[-0.40824829+0.j          0.24400118-0.40702229j  0.24400118+0.40702229j]
 [-0.40824829+0.j         -0.41621909-0.40702229j -0.41621909+0.40702229j]
 [-0.81649658+0.j         -0.66022027+0.j         -0.66022027-0.j        ]]
矩阵与特征向量的乘积: [[-1.63299316+0.00000000e+00j -0.48800237+8.14044580e-01j
  -0.48800237-8.14044580e-01j]
 [-1.63299316+0.00000000e+00j  0.83243817+8.14044580e-01j
   0.83243817-8.14044580e-01j]
 [-3.26598632+0.00000000e+00j  1.32044054-5.55111512e-16j
   1.32044054+5.55111512e-16j]]
特征值与特征向量的乘积: [[0.81649658+4.50974724e-16j 3.12888345-8.14044580e-01j
  3.12888345+8.14044580e-01j]]
验证二者是否相等: [[False False False]
 [False False False]
 [False False False]]
"""
# 逆矩阵
A=np.matrix([[1,2],[3,4]])
B=np.linalg.inv(A)
print ("逆矩阵:\n",B)
print("AB乘积(对角线元素为1,其余近似为0):\n",A*B)

"""
逆矩阵:
 [[-2.   1. ]
 [ 1.5 -0.5]]
AB乘积(对角线元素为1,其余近似为0):
 [[1.0000000e+00 0.0000000e+00]
 [8.8817842e-16 1.0000000e+00]]
"""

​ 奇异值分解(Singular Value Decomposition , sVD )可以把大矩阵分解成几个更小矩阵的乘积,达到数据降维和去噪的效果。这是机器学习算法中主成分分析算法的理论基础。numpy中线性代数子模块linalg提供了计算奇异值分解的svd()函数。

​ svd()函数将矩阵A分解为u*np.diag(s)*v的形式并返回u、s、v,其中数组s中的元素就是矩阵A的奇异值。

# 奇异值分解
A=np.matrix([[1,2,3],[4,5,6],[7,8,9]])
u,s,v=np.linalg.svd(A)
print("u=",u)
print("s=",s)
print("v=",v)

"""
u= [[-0.21483724  0.88723069  0.40824829]
 [-0.52058739  0.24964395 -0.81649658]
 [-0.82633754 -0.38794278  0.40824829]]
s= [1.68481034e+01 1.06836951e+00 3.33475287e-16]
v= [[-0.47967118 -0.57236779 -0.66506441]
 [-0.77669099 -0.07568647  0.62531805]
 [-0.40824829  0.81649658 -0.40824829]]
"""
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值