基于我下面链接的相关问题(请参见@Aleh solution):我希望只计算给定幂的矩阵中列之间的唯一乘积。
例如,对于N=5,M=3,p=2,我们得到列(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)的乘积。我想修改(@Aleh)代码,只计算(1,1)、(1,2)、(1,3)、(2,2)、(2,3)、(3,3)列之间的乘积。但我想对每个第p个订单都这样做。
有人能帮我在R里完成这个吗?
非常感谢!
相关问题:R-给定一个矩阵和一个幂,生成包含所有矩阵列组合的多个矩阵
如果我没理解错的话,那么这就是你要找的:
# all combinations of p elements out of M with repetiton
# c.f. http://www.mathsisfun.com/combinatorics/combinations-permutations.html
comb_rep <- function(p, M) {
combn(M + p - 1, p) - 0:(p - 1)
}
# use cols from mat to form a new matrix
# take row products
col_prod <- function(cols, mat) {
apply(mat[ ,cols], 1, prod)
}
N <- 5
M <- 3
p <- 3
mat <- matrix(1:(N*M),N,M)
col_comb <- lapply(2:p, comb_rep, M)
col_comb
#> [[1]]
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 1 1 1 2 2 3
#> [2,] 1 2 3 2 3 3
#>
#> [[2]]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 1 1 1 1 1 2 2 2 3
#> [2,] 1 1 1 2 2 3 2 2 3 3
#> [3,] 1 2 3 2 3 3 2 3 3 3
# prepend original matrix
res_mat <- list()
res_mat[[1]] <- mat
c(res_mat,
lapply(col_comb, function(cols) apply(cols, 2, col_prod, mat)))
#> [[1]]
#> [,1] [,2] [,3]
#> [1,] 1 6 11
#> [2,] 2 7 12
#> [3,] 3 8 13
#> [4,] 4 9 14
#> [5,] 5 10 15
#>
#> [[2]]
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 1 6 11 36 66 121
#> [2,] 4 14 24 49 84 144
#> [3,] 9 24 39 64 104 169
#> [4,] 16 36 56 81 126 196
#> [5,] 25 50 75 100 150 225
#>
#> [[3]]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 6 11 36 66 121 216 396 726 1331
#> [2,] 8 28 48 98 168 288 343 588 1008 1728
#> [3,] 27 72 117 192 312 507 512 832 1352 2197
#> [4,] 64 144 224 324 504 784 729 1134 1764 2744
#> [5,] 125 250 375 500 750 1125 1000 1500 2250 3375
然而,这不是真正有效的,因为例如,第三次方是从原始矩阵的三列计算的,而不是原始矩阵的一列和第二次方的一列。
编辑:用评论中提到的真实大小进行测试表明,@Moody_Mudskipper的乘法方法要快得多,而我的组合方法要快一点。所以将两者结合起来是有意义的:
# original function from @Moody_Mudskipper's answer
fun <- function(mat,p) {
mat <- as.data.frame(mat)
combs <- do.call(expand.grid,rep(list(seq(ncol(mat))),p)) # all combinations including permutations of same values
combs <- combs[!apply(combs,1,is.unsorted),] # "unique" permutations only
rownames(combs) <- apply(combs,1,paste,collapse="-") # Just for display of output, we keep info of combinations in rownames
combs <- combs[order(rownames(combs)),] # sort to have desired column order on output
apply(combs,1,function(x) Reduce(`*`,mat[,x])) # multiply the relevant columns
}
combined <- function(mat, p) {
mat <- as.data.frame(mat)
combs <- combn(ncol(mat) + p - 1, p) - 0:(p - 1) # all combinations with repetition
colnames(combs) <- apply(combs, 2, paste, collapse = "-") # Just for display of output, we keep info of combinations in colnames
apply(combs, 2, function(x) Reduce(`*`, mat[ ,x])) # multiply the relevant columns
}
N <- 10000
M <- 25
p <- 4
mat <- matrix(runif(N*M),N,M)
microbenchmark::microbenchmark(
fun(mat, p),
combined(mat, p),
times = 10
)
#> Unit: seconds
#> expr min lq mean median uq max neval
#> fun(mat, p) 3.456853 3.698680 4.067995 4.032647 4.341944 4.869527 10
#> combined(mat, p) 2.543994 2.738313 2.870446 2.793768 3.090498 3.254232 10
请注意,对于M,这两个函数不会产生相同的结果
我们创建以下函数,该函数将所有“唯一”排列与所选的p
相乘:
fun <- function(mat,p) {
mat <- as.data.frame(mat)
combs <- do.call(expand.grid,rep(list(seq(ncol(mat))),p)) # all combinations including permutations of same values
combs <- combs[!apply(combs,1,is.unsorted),] # "unique" permutations only
rownames(combs) <- apply(combs,1,paste,collapse="-") # Just for display of output, we keep info of combinations in rownames
combs <- combs[order(rownames(combs)),] # sort to have desired column order on output
apply(combs,1,function(x) Reduce(`*`,mat[,x])) # multiply the relevant columns
}
例子
N = 5
M = 3
mat1 = matrix(1:(N*M),N,M)
# [,1] [,2] [,3]
# [1,] 1 6 11
# [2,] 2 7 12
# [3,] 3 8 13
# [4,] 4 9 14
# [5,] 5 10 15
M = 4
mat2 = matrix(1:(N*M),N,M)
# [,1] [,2] [,3] [,4]
# [1,] 1 6 11 16
# [2,] 2 7 12 17
# [3,] 3 8 13 18
# [4,] 4 9 14 19
# [5,] 5 10 15 20
lapply(2:4,fun,mat=mat1)
# [[1]]
# 1-1 1-2 1-3 2-2 2-3 3-3
# [1,] 1 6 11 36 66 121
# [2,] 4 14 24 49 84 144
# [3,] 9 24 39 64 104 169
# [4,] 16 36 56 81 126 196
# [5,] 25 50 75 100 150 225
#
# [[2]]
# 1-1-1 1-1-2 1-1-3 1-2-2 1-2-3 1-3-3 2-2-2 2-2-3 2-3-3 3-3-3
# [1,] 1 6 11 36 66 121 216 396 726 1331
# [2,] 8 28 48 98 168 288 343 588 1008 1728
# [3,] 27 72 117 192 312 507 512 832 1352 2197
# [4,] 64 144 224 324 504 784 729 1134 1764 2744
# [5,] 125 250 375 500 750 1125 1000 1500 2250 3375
#
# [[3]]
# 1-1-1-1 1-1-1-2 1-1-1-3 1-1-2-2 1-1-2-3 1-1-3-3 1-2-2-2 1-2-2-3 1-2-3-3 1-3-3-3 2-2-2-2 2-2-2-3 2-2-3-3 2-3-3-3 3-3-3-3
# [1,] 1 6 11 36 66 121 216 396 726 1331 1296 2376 4356 7986 14641
# [2,] 16 56 96 196 336 576 686 1176 2016 3456 2401 4116 7056 12096 20736
# [3,] 81 216 351 576 936 1521 1536 2496 4056 6591 4096 6656 10816 17576 28561
# [4,] 256 576 896 1296 2016 3136 2916 4536 7056 10976 6561 10206 15876 24696 38416
# [5,] 625 1250 1875 2500 3750 5625 5000 7500 11250 16875 10000 15000 22500 33750 50625
fun(mat2,2)
# 1-1 1-2 1-3 1-4 2-2 2-3 2-4 3-3 3-4 4-4
# [1,] 1 6 11 16 36 66 96 121 176 256
# [2,] 4 14 24 34 49 84 119 144 204 289
# [3,] 9 24 39 54 64 104 144 169 234 324
# [4,] 16 36 56 76 81 126 171 196 266 361
# [5,] 25 50 75 100 100 150 200 225 300 400
给定矩阵(大小by)和幂,(例如,4),产生矩阵,其中每个-th矩阵包含所有中的列在该程度上的可能组合。 在我当前的方法中,我生成-th矩阵,然后在下一次调用中使用它来生成th矩阵。对于给定的功率,这是否可以“自动”完成,而不是手动完成? 说到R,我是一个新手,我明白有可能比下面的尝试更有效、更优雅地实现这个解决方案。。。 有人能提供一些建议吗?我的目标是为给定的矩阵创建一个函数,并以更“自动化”
我正在使用OpenCV一段时间,现在我需要这种类型的乘法: 定义一个矩阵,其中包含类型为1的元素。矩阵的大小为:M X N。矩阵必须与Vector相乘,Vector的大小为:N X 1,包含双
问题内容: 我正在尝试编写一种算法,用于在给定的子矩阵中查找子矩阵。为了解决这个问题,我编写了以下代码: 这段代码可以正常工作,但是我不确定这是问题的确切解决方案还是可以解决。请提供您的专家意见。提前致谢。 问题答案: 该算法对4×4矩阵和2×2子矩阵进行了硬编码。否则,它看起来像蛮力算法。 我会这样表示: 如果您想要更有效的方法,建议您将它们压扁,如下所示: 并在此序列中搜索以下模式: 使用标准
MATLAB提供产生基本矩阵的四个函数: zeros 产生一个全零矩阵 ones 产生一个全1矩阵 rand 产生一个元素是均匀分布随机数的矩阵 randn 产生一个元素是正态分布的随机数的矩阵 例如: Z = zeros(2,4) Z = 0 0 0 0 0 0 0 0 F = 5*ones(3,3) F = 5
问题内容: 我有以下内容: 如何在XYZ_2上执行与在XYZ_2上相同的操作?我会以某种方式首先重塑数组吗? 问题答案: 您似乎正在尝试的最后一个轴 与最后一个 。因此,您可以像这样使用- 相关帖子了解。 为了完整起见,在交换的最后两个轴后,我们当然也可以使用,例如- 这将不如一个高效。 运行时测试- 一般而言,涉及张量时,效率要高得多。由于的轴只有一个,因此我们可以通过重整,使用,获取结果并将其
我有一个由6列组成的数据框。生成矩阵的最快方法是什么,该矩阵具有以下功能: 步骤1)col1*col1a, col2*col2a, col3*col3a, col4*col4a 步骤2)col_new=(col1*col1a)-col2*col2a)/(col1a-col2a) 使用for循环是选择之一——但是有什么方法可以更快地实现这一点。 我需要有1x3,1x4,1x5,2x3,2x4等等的列