概述
#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()填补元素的情况 |
######################################### |
最后
以上就是重要朋友为你收集整理的R语言-矩阵的全部内容,希望文章能够帮你解决R语言-矩阵所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复