R语言-矩阵

#2.1.3矩阵(Matrix)
#矩阵:一个二维数组
#矩阵的每个元素都必须具有相同的数据类型
### 1.矩阵的创建与引用 ###
#生成一个矩阵
matrix(vector,nrow=number_of_rows,ncol=number_of_columns,byrow=T/F)
diag() #生成一个对角矩阵
#例:
# 生成全部是0的矩阵
(zero = matrix(0, nrow = 3, ncol = 3))
##       [,1] [,2] [,3]
##  [1,]    0    0    0
##  [2,]    0    0    0
##  [3,]    0    0    0
# 生成一个对角全是1的矩阵,直接在diag中输入对角线向量即可
(dig = diag(rep(1, 4)))
##       [,1] [,2] [,3] [,4]
##  [1,]    1    0    0    0
##  [2,]    0    1    0    0
##  [3,]    0    0    1    0
##  [4,]    0    0    0    1
#额外备注
rep(x,n) #将vector x的值循环n遍 
#例:
rep(1, 4)
##[1] 1 1 1 1
rep(1:4, 2)
##[1] 1 2 3 4 1 2 3 4
#观察区别
diag(1:4)
##     [,1] [,2] [,3] [,4]
##[1,]    1    0    0    0
##[2,]    0    2    0    0
##[3,]    0    0    3    0
##[4,]    0    0    0    4
diag(4)
##[,1] [,2] [,3] [,4]
##[1,]    1    0    0    0
##[2,]    0    1    0    0
##[3,]    0    0    1    0
##[4,]    0    0    0    1
#从已有向量1:12数据转化成矩阵,如果没写byrow=T,默认将向量按列排序
(M = matrix(1:12, nrow = 3, ncol = 4))
##       [,1] [,2] [,3] [,4]
##  [1,]    1    4    7   10
##  [2,]    2    5    8   11
##  [3,]    3    6    9   12
#以向量1:4为对角线的对角矩阵(重复例子,上面已有)
(N = diag(1:4))
##       [,1] [,2] [,3] [,4]
##  [1,]    1    0    0    0
##  [2,]    0    2    0    0
##  [3,]    0    0    3    0
##  [4,]    0    0    0    4
### 2.矩阵的常用操作 ###
## (1) 矩阵概览 ##
# 查看矩阵的维度/行列数
dim(M) 
##  [1] 3 4
# 提取矩阵的行数
nrow(M) 
##  [1] 3
# 提取矩阵的列数
ncol(M)
##  [1] 4
# 引用元素
M[1, 2]
##  [1] 4
M[1:2, 2:3]
##       [,1] [,2]
##  [1,]    4    7
##  [2,]    5    8
# 给行列命名
colnames(M) = paste0("x_", 1:4)
rownames(M) = (letters[1:3])
M
##    x_1 x_2 x_3 x_4
##a   1   4   7  10
##b   2   5   8  11
##c   3   6   9  12
colnames(M) = 1:4
rownames(M) = c("一","二","三")
M
##   1 2 3  4
##一 1 4 7 10
##二 2 5 8 11
##三 3 6 9 12
colnames(M) = paste0("x_", 1:4)
rownames(M) = 1:3; M
##    x_1 x_2 x_3 x_4
##  1   1   4   7  10
##  2   2   5   8  11
##  3   3   6   9  12
# 同样的命令可调用行列名
colnames(M)
##  [1] "x_1" "x_2" "x_3" "x_4"
rownames(M)
##  [1] "1" "2" "3"
## (2) 将多个矩阵合并 ##
cbind() #按列合并
rbind() #按行合并
#例:
(A = matrix(1:9, nrow = 3, ncol = 3, byrow = T))
##       [,1] [,2] [,3]
##  [1,]    1    2    3
##  [2,]    4    5    6
##  [3,]    7    8    9
(B = diag(11:13))
##       [,1] [,2] [,3]
##  [1,]   11    0    0
##  [2,]    0   12    0
##  [3,]    0    0   13
rbind(A, B) 
##       [,1] [,2] [,3]
##  [1,]    1    2    3
##  [2,]    4    5    6
##  [3,]    7    8    9
##  [4,]   11    0    0
##  [5,]    0   12    0
##  [6,]    0    0   13
cbind(A, B) 
##       [,1] [,2] [,3] [,4] [,5] [,6]
##  [1,]    1    2    3   11    0    0
##  [2,]    4    5    6    0   12    0
##  [3,]    7    8    9    0    0   13
### 3.矩阵的数学操作 ###
## (1) 矩阵的加减乘运算 ##
A + B
##       [,1] [,2] [,3]
##  [1,]   12    2    3
##  [2,]    4   17    6
##  [3,]    7    8   22
A - B
##       [,1] [,2] [,3]
##  [1,]  -10    2    3
##  [2,]    4   -7    6
##  [3,]    7    8   -4
A * B #错误的!!!仅仅是各个元素对应相乘
##       [,1] [,2] [,3]
##  [1,]   11    0    0
##  [2,]    0   60    0
##  [3,]    0    0  117
A %*% B #矩阵的乘法,线性代数的乘法
##       [,1] [,2] [,3]
##  [1,]   11   24   39
##  [2,]   44   60   78
##  [3,]   77   96  117
solve() #求矩阵的逆
#例:
hilbert <- function(n) { i <- 1:n; 1 / outer(i - 1, i, "+") }
h8 <- hilbert(8); h8
##[,1]      [,2]      [,3]       [,4]       [,5]       [,6]       [,7]       [,8]
##[1,] 1.0000000 0.5000000 0.3333333 0.25000000 0.20000000 0.16666667 0.14285714 0.12500000
##[2,] 0.5000000 0.3333333 0.2500000 0.20000000 0.16666667 0.14285714 0.12500000 0.11111111
##[3,] 0.3333333 0.2500000 0.2000000 0.16666667 0.14285714 0.12500000 0.11111111 0.10000000
##[4,] 0.2500000 0.2000000 0.1666667 0.14285714 0.12500000 0.11111111 0.10000000 0.09090909
##[5,] 0.2000000 0.1666667 0.1428571 0.12500000 0.11111111 0.10000000 0.09090909 0.08333333
##[6,] 0.1666667 0.1428571 0.1250000 0.11111111 0.10000000 0.09090909 0.08333333 0.07692308
##[7,] 0.1428571 0.1250000 0.1111111 0.10000000 0.09090909 0.08333333 0.07692308 0.07142857
##[8,] 0.1250000 0.1111111 0.1000000 0.09090909 0.08333333 0.07692308 0.07142857 0.06666667
sh8 <- solve(h8);sh8
##[,1]      [,2]       [,3]       [,4]        [,5]        [,6]        [,7]       [,8]
##[1,]      64     -2016      20160     -92400      221760     -288288      192192     -51480
##[2,]   -2016     84672    -952560    4656960   -11642400    15567552   -10594584    2882880
##[3,]   20160   -952560   11430720  -58212000   149688000  -204324119   141261119  -38918880
##[4,]  -92400   4656960  -58212000  304919999  -800414996  1109908794  -776936155  216215998
##[5,]  221760 -11642400  149688000 -800414996  2134439987 -2996753738  2118916783 -594593995
##[6,] -288288  15567552 -204324119 1109908793 -2996753738  4249941661 -3030050996  856215352
##[7,]  192192 -10594584  141261119 -776936154  2118916782 -3030050996  2175421226 -618377753
##[8,]  -51480   2882880  -38918880  216215998  -594593995   856215351  -618377753  176679358
round(sh8 %*% h8, 3)
##[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
##[1,]    1    0    0    0    0    0    0    0
##[2,]    0    1    0    0    0    0    0    0
##[3,]    0    0    1    0    0    0    0    0
##[4,]    0    0    0    1    0    0    0    0
##[5,]    0    0    0    0    1    0    0    0
##[6,]    0    0    0    0    0    1    0    0
##[7,]    0    0    0    0    0    0    1    0
##[8,]    0    0    0    0    0    0    0    1
#矩阵的数学操作函数
A+B;A-B;A*B #对矩阵的各个元素完成加减乘运算
A%*%B #矩阵乘法
crossprod(A,B) #矩阵A的转置与矩阵B的乘法
tcrossprod(A,B) #矩阵A与矩阵B的转置的乘法
t(A) #求矩阵A的转置
solve(A) #求矩阵A的逆
eigen(A) #对矩阵进行特征值分解,结果输出特征值及特征向量
svd(A) #对矩阵进行svd奇异值分解,结果可输出矩阵A的奇异值及两个正交阵U,V
#例:
# 矩阵的转置、求逆及分解
#原型:
(A = matrix(1:9, nrow = 3, ncol = 3, byrow = T))
##[,1] [,2] [,3]
##[1,]    1    2    3
##[2,]    4    5    6
##[3,]    7    8    9
(B = diag(11:13))
##[,1] [,2] [,3]
##[1,]   11    0    0
##[2,]    0   12    0
##[3,]    0    0   13
#求:
solve(B)  # 求矩阵逆
##             [,1]       [,2]       [,3]
##  [1,] 0.09090909 0.00000000 0.00000000
##  [2,] 0.00000000 0.08333333 0.00000000
##  [3,] 0.00000000 0.00000000 0.07692308
t(A)      # 求矩阵转置
##       [,1] [,2] [,3]
##  [1,]    1    4    7
##  [2,]    2    5    8
##  [3,]    3    6    9
eigen(A)  # 特征值分解
##  eigen() decomposition
##  $values
##  [1]  1.611684e+01 -1.116844e+00 -1.303678e-15
##  
##  $vectors
##             [,1]        [,2]       [,3]
##  [1,] -0.2319707 -0.78583024  0.4082483
##  [2,] -0.5253221 -0.08675134 -0.8164966
##  [3,] -0.8186735  0.61232756  0.4082483
svd(A)    # 奇异值svd分解
##  $d
##  [1] 1.684810e+01 1.068370e+00 4.418425e-16
##  
##  $u
##             [,1]       [,2]       [,3]
##  [1,] -0.2148372  0.8872307  0.4082483
##  [2,] -0.5205874  0.2496440 -0.8164966
##  [3,] -0.8263375 -0.3879428  0.4082483
##  
##  $v
##             [,1]        [,2]       [,3]
##  [1,] -0.4796712 -0.77669099 -0.4082483
##  [2,] -0.5723678 -0.07568647  0.8164966
##  [3,] -0.6650644  0.62531805 -0.4082483
## (2) rARPACK的应用 ##
# 打开这个包
# install.packages("rARPACK")
library(rARPACK) #rARPACK包主要针对大规模矩阵运算
eigs() #进行特征值分解
svds() #进行SVD分解
# 构造一个1000维的大型矩阵
T = matrix(1:1000000, 1000, 1000)
# 正常分解与快速分解的对比,此处以选择前5个特征(奇异)值为例
system.time(svd(T))
## 用户 系统 流逝 
## 2.07 0.00 2.08
system.time(svds(T, 5)) 
## 用户 系统 流逝 
## 0.06 0.00 0.08 
system.time(eigen(T))
## 用户 系统 流逝 
## 4.33 0.02 4.35 
system.time(eigs(T, 5))
## 用户 系统 流逝 
## 0.12 0.00 0.12
#额外备注:system.time()统计一个程序运行时间的函数
#如果里面用的是一个程序,那就用大括号{}括起来
#例:
a = 1+1
system.time({a = 1+1})
## 用户 系统 流逝 
## 0    0    0 
## (3) 稀疏矩阵 ##
# install.packages("Matrix")
library(Matrix) #Matrix包提供了很多独特的存储、处理稀疏矩阵的方法
#生成稀疏矩阵的两个函数:Matrix()和spMatrix()
Matrix(vector,nrow=number_of_row,ncol=number_of_column,sparse = TRUE/FALSE)
#Matrix()和matrix()类似,区别在于需要设定参数Sparse=T或F来定于是否稀疏矩阵
#假如Sparse=T,则会生成dgCMatrix稀疏矩阵类型,先将列按顺序排好再存储起来的方式存储
#假如不设定该参数,则会自动数矩阵中的0的个数,超过一半就会设置为稀疏模式
#例:
# 生成普通矩阵
vector = c(1:3, rep(0, 5), 6:9)
(m1 = matrix(vector, nrow = 3, ncol = 4))
##       [,1] [,2] [,3] [,4]
##  [1,]    1    0    0    7
##  [2,]    2    0    0    8
##  [3,]    3    0    6    9
# 生成稀疏矩阵方法1
(m2 = Matrix(vector, nrow = 3 ,ncol = 4, sparse = TRUE))
##  3 x 4 sparse Matrix of class "dgCMatrix"
##              
##  [1,] 1 . . 7
##  [2,] 2 . . 8
##  [3,] 3 . 6 9
(m3 = Matrix(vector, nrow = 3 ,ncol = 4, sparse = FALSE))
##  3 x 4 Matrix of class "dgeMatrix"
##       [,1] [,2] [,3] [,4]
##  [1,]    1    0    0    7
##  [2,]    2    0    0    8
##  [3,]    3    0    6    9
spMatrix(nrow,ncol,i=integer(),j=integer(),x=numeric()) 
#前两个参数设定矩阵的行列数,i设定需要填补数字的行号,j为列号,x就是需要填补的元素
#spMatrix()函数则通过定义非0元素的行列位置来生成dgTMatrix稀疏矩阵类型
#dgTMatrix稀疏矩阵类型存储方式是将非0元素所在的行、列以及它的值构成一个三元组(i,j,v),再按某种规律把它们存储起来
#例:
# 生成稀疏矩阵方法2
(m4 = spMatrix(10, 20, i = c(1, 3:8), j = c(2, 9, 6:10), x = 7 * (1:7)))
##  10 x 20 sparse Matrix of class "dgTMatrix"
##                                                    
##   [1,] . 7 . . .  .  .  .  .  . . . . . . . . . . .
##   [2,] . . . . .  .  .  .  .  . . . . . . . . . . .
##   [3,] . . . . .  .  .  . 14  . . . . . . . . . . .
##   [4,] . . . . . 21  .  .  .  . . . . . . . . . . .
##   [5,] . . . . .  . 28  .  .  . . . . . . . . . . .
##   [6,] . . . . .  .  . 35  .  . . . . . . . . . . .
##   [7,] . . . . .  .  .  . 42  . . . . . . . . . . .
##   [8,] . . . . .  .  .  .  . 49 . . . . . . . . . .
##   [9,] . . . . .  .  .  .  .  . . . . . . . . . . .
##  [10,] . . . . .  .  .  .  .  . . . . . . . . . . .
summary(m4) #统一看到它填补元素的情况
##  10 x 20 sparse Matrix of class "dgTMatrix", with 7 entries 
##    i  j  x
##  1 1  2  7
##  2 3  9 14
##  3 4  6 21
##  4 5  7 28
##  5 6  8 35
##  6 7  9 42
##  7 8 10 49
# 当行列数分别为10000时,稀疏矩阵的内存大小和生成时间优势均很明显。
n = 10000
m1 = matrix(0, nrow = n, ncol = n)
m2 = Matrix(0, nrow = n, ncol = n, sparse = TRUE)
object.size(m1); object.size(m2) #求占的内存大小
##  800000200 bytes
##  41632 bytes 
system.time(matrix(0, nrow = n, ncol = n)) #统计运行时间
##     user  system elapsed 
##     0.29    0.14    0.42
system.time(Matrix(0, nrow = n, ncol = n, sparse = TRUE))
##     user  system elapsed 
##        0       0       0
# 两种矩阵计算区别
n = 1000
dat = sample(c(0, 1), n^2, replace = TRUE, prob = c(0.9, 0.1))
m1 = matrix(dat, nrow = n, ncol = n); m1[1:6, 1:6]
##       [,1] [,2] [,3] [,4] [,5] [,6]
##  [1,]    0    0    0    0    0    0
##  [2,]    0    0    0    0    0    0
##  [3,]    0    0    0    0    0    1
##  [4,]    0    0    0    0    1    0
##  [5,]    0    1    1    1    0    0
##  [6,]    0    0    0    0    0    1
m2 = Matrix(dat, nrow = n, ncol = n, sparse = TRUE); m2[1:6, 1:6]
##  6 x 6 sparse Matrix of class "dgCMatrix"
##                  
##  [1,] . . . . . .
##  [2,] . . . . . .
##  [3,] . . . . . 1
##  [4,] . . . . 1 .
##  [5,] . 1 1 1 . .
##  [6,] . . . . . 1
# 求乘积运算时间对比
system.time(m1 %*% t(m1))
##     user  system elapsed 
##     1.04    0.00    1.08
system.time(m2 %*% t(m1))
##     user  system elapsed 
##     0.14    0.00    0.16
#########################################
#总结#
 
matrix(vector,nrow=number_of_rows,ncol=number_of_columns,byrow=T/F) #生成一个矩阵
diag() #生成一个对角矩阵
rep(x,n) #将vector x的值循环n遍 
dim(M)# 查看矩阵的维度/行列数
nrow(M) # 提取矩阵的行数
ncol(M) # 提取矩阵的列数
M[1, 2] # 引用元素
M[1:2, 2:3] # 引用元素
colnames(M) = paste0("x_", 1:4) # 给列命名
rownames(M) = (letters[1:3]) # 给行命名
colnames(M) = 1:4  # 给列命名
rownames(M) = c("一","二","三") # 给行命名
colnames(M) # 同样的命令可调用行名
rownames(M) # 同样的命令可调用列名
cbind() #按列合并
rbind() #按行合并
#矩阵的数学操作函数
A+B;A-B;A*B #对矩阵的各个元素完成加减乘运算
A%*%B #矩阵乘法
crossprod(A,B) #矩阵A的转置与矩阵B的乘法
tcrossprod(A,B) #矩阵A与矩阵B的转置的乘法
t(A) #求矩阵A的转置
solve(A) #求矩阵A的逆
eigen(A) #对矩阵进行特征值分解,结果输出特征值及特征向量
svd(A) #对矩阵进行svd奇异值分解,结果可输出矩阵A的奇异值及两个正交阵U,V
#rARPACK包
library(rARPACK) #rARPACK包主要针对大规模矩阵运算
eigs() #进行特征值分解
svds() #进行SVD分解
system.time() #统计一个程序运行时间的函数
library(Matrix) #Matrix包提供了很多独特的存储、处理稀疏矩阵的方法(做大规模矩阵运算使用的包)
Matrix(vector,nrow=number_of_row,ncol=number_of_column,sparse = TRUE/FALSE)#Sparse=T,则会生成dgCMatrix稀疏矩阵类型
spMatrix(nrow,ncol,i=integer(),j=integer(),x=numeric())#dgTMatrix稀疏矩阵类型
summary() #统一看到spMatrix()填补元素的情况
#########################################
  • 4
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值