반응형
행렬의 행에 벡터를 곱 하시겠습니까?
matrix
25 개의 열과 23 개의 행 이있는 숫자 와 길이가 25 인 벡터가 있습니다. for
루프 를 사용하지 않고 행렬의 각 행에 벡터를 어떻게 곱할 수 있습니까?
결과는 25x23 행렬 (입력과 동일한 크기)이어야하지만 각 행에 벡터를 곱했습니다.
@hatmatrix의 답변에서 재현 가능한 예를 추가했습니다.
matrix <- matrix(rep(1:3,each=5),nrow=3,ncol=5,byrow=TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
vector <- 1:5
원하는 출력 :
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 2 4 6 8 10
[3,] 3 6 9 12 15
나는 당신이 찾고 있다고 생각합니다 sweep()
.
# Create example data and vector
mat <- matrix(rep(1:3,each=5),nrow=3,ncol=5,byrow=TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
vec <- 1:5
# Use sweep to apply the vector with the multiply (`*`) function
# across columns (See ?apply for an explanation of MARGIN)
sweep(mat, MARGIN=2, vec, `*`)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 2 4 6 8 10
[3,] 3 6 9 12 15
수년에 걸쳐 개선되었지만 R의 핵심 기능 중 하나였습니다.
> MyMatrix <- matrix(c(1,2,3, 11,12,13), nrow = 2, ncol=3, byrow=TRUE)
> MyMatrix
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 11 12 13
> MyVector <- c(1:3)
> MyVector
[1] 1 2 3
다음 중 하나를 사용할 수 있습니다.
> t(t(MyMatrix) * MyVector)
[,1] [,2] [,3]
[1,] 1 4 9
[2,] 11 24 39
또는:
> MyMatrix %*% diag(MyVector)
[,1] [,2] [,3]
[1,] 1 4 9
[2,] 11 24 39
사실 sweep
내 컴퓨터에서 가장 빠른 옵션은 아닙니다.
MyMatrix <- matrix(c(1:1e6), ncol=1e4, byrow=TRUE)
MyVector <- c(1:1e4)
Rprof(tmp <- tempfile(),interval = 0.001)
t(t(MyMatrix) * MyVector) # first option
Rprof()
MyTimerTranspose=summaryRprof(tmp)$sampling.time
unlink(tmp)
Rprof(tmp <- tempfile(),interval = 0.001)
MyMatrix %*% diag(MyVector) # second option
Rprof()
MyTimerDiag=summaryRprof(tmp)$sampling.time
unlink(tmp)
Rprof(tmp <- tempfile(),interval = 0.001)
sweep(MyMatrix ,MARGIN=2,MyVector,`*`) # third option
Rprof()
MyTimerSweep=summaryRprof(tmp)$sampling.time
unlink(tmp)
Rprof(tmp <- tempfile(),interval = 0.001)
t(t(MyMatrix) * MyVector) # first option again, to check order
Rprof()
MyTimerTransposeAgain=summaryRprof(tmp)$sampling.time
unlink(tmp)
MyTimerTranspose
MyTimerDiag
MyTimerSweep
MyTimerTransposeAgain
결과 :
> MyTimerTranspose
[1] 0.04
> MyTimerDiag
[1] 40.722
> MyTimerSweep
[1] 33.774
> MyTimerTransposeAgain
[1] 0.043
On top of being the slowest option, the second option reaches the memory limit (2046 MB). However, considering the remaining options, the double transposition seems a lot better than sweep
in my opinion.
Edit
Just trying smaller data a repeated number of times:
MyMatrix <- matrix(c(1:1e3), ncol=1e1, byrow=TRUE)
MyVector <- c(1:1e1)
n=100000
[...]
for(i in 1:n){
# your option
}
[...]
> MyTimerTranspose
[1] 5.383
> MyTimerDiag
[1] 6.404
> MyTimerSweep
[1] 12.843
> MyTimerTransposeAgain
[1] 5.428
For speed one may create matrix from the vector before multiplying
mat <- matrix(rnorm(1e6), ncol=1e4)
vec <- c(1:1e4)
mat * matrix(vec, dim(mat)[1], length(vec))
library(microbenchmark)
microbenchmark(
transpose = t(t(mat) * vec),
make_matrix = mat * matrix(vec, dim(mat)[1], length(vec), byrow = TRUE),
sweep = sweep(mat,MARGIN=2,vec,`*`))
#Unit: milliseconds
# expr min lq mean median uq max neval cld
# transpose 9.940555 10.480306 14.39822 11.210735 16.19555 77.67995 100 b
#make_matrix 5.556848 6.053933 9.48699 6.662592 10.74121 74.14429 100 a
# sweep 8.033019 8.500464 13.45724 12.331015 14.14869 77.00371 100 b
참고URL : https://stackoverflow.com/questions/3643555/multiply-rows-of-matrix-by-vector
반응형
'IT Share you' 카테고리의 다른 글
정수를 파이썬에서 가장 짧은 URL 안전 문자열로 변환하는 방법은 무엇입니까? (0) | 2020.11.23 |
---|---|
파일이 존재하고 C ++에서 읽을 수 있는지 확인하는 방법은 무엇입니까? (0) | 2020.11.23 |
동일한 사용자 이름으로 다른 테이블의 테이블 값 업데이트 (0) | 2020.11.23 |
jQuery Mobile에서 버튼 비활성화 (0) | 2020.11.23 |
Python 목록에서 항목의 마지막 항목을 찾는 방법 (0) | 2020.11.23 |