粘贴n * n矩阵或数据框的所有可能的对角线 [英] Paste all possible diagonals of an n*n matrix or dataframe

查看:120
本文介绍了粘贴n * n矩阵或数据框的所有可能的对角线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



例如,考虑以下3个X 3矩阵:

 #创建矩阵,转换为字符数据帧
matrix< - matrix(data = c('s' ,'t','y','a','e','l','f','n','e'),nrow = 3,ncol = 3)
matrix< as.data.frame(matrix)
for(i in 1:length(colnames(matrix))){
matrix [,i]< - as.character(matrix [,i])
}

在上面的矩阵中,我需要粘贴对角线:see,fey ,ees和yef。我可以在数据框中找到以下代码:

  diag<  -  paste(matrix [1,1] [2,2]矩阵[3,3],sep ='')
diag1< - paste(matrix [1,3],matrix [2,2],matrix [3,1],sep ='')
diag2< - paste(matrix [3,1],matrix [2,2],matrix [1,3],sep ='')
diag3< - paste矩阵[3,3],矩阵[2,2],矩阵[1,1],sep ='')

问题是我想自动化这个,以便它可以在任何N×N矩阵上工作。 (我正在写一个函数来找到任何N×N矩阵中的对角线)。有没有一个有效的方法来实现?

解决方案

哦,这很容易,如果你使用矩阵而不是data.frame :)
我们可以选择矩阵元素,就像我们可以使用矢量元素:

 矩阵[1:3]#前三个元素==第一列

n< - ncol(matrix)
(1:n-1)* n + 1:n
## [1] 1 5 9
(1:n-1)* n + n:1
## [1] 3 5 7

所以现在我们可以使用这个:

 矩阵[(1:n-1)* n + 1 :n] 
[1]see
paste0(matrix [(1:n-1)* n + 1:n],collapse =)
[1]看到

如果你想向后退,只需使用 rev function:

  paste0(matrix [rev((1:n -1)* n + 1:n)],collapse =)
[1]ees

一些基准:

  rotate<  -  function(x)t(apply(x,2,rev ))
revMat< - function(mat,dir = 0){
x < if(bitwAnd(dir,1))rev(seq(nrow(mat)))else seq(nrow(mat))
y< - if(bitwAnd(dir,2))rev )))else seq(nrow(mat))
mat [x,y]
}

bartek< - function(matrix){
n < ncol(matrix)
c(paste0(matrix [(1:n-1)* n + 1:n],collapse =),paste0(matrix [rev((1:n-1) 1:n)],collapse =),
paste0(matrix [(1:n-1)* n + n:1],collapse =),paste0(matrix [rev n-1)* n + n:1)],collapse =))
}

Joe< - function(matrix){
diag0 < (矩阵)
diag1< - diag(rotate(matrix))
diag2 < - rev(diag0)
diag3< - rev(diag1)
c(paste ,collapse =),paste(diag1,collapse =),
paste(diag2,collapse =),paste(diag3,collapse =))
}

James< - function(mat){
sapply(0:3,function(x)paste(diag(revMat(mat,x)),collapse =))
}

矩阵矩阵(c('s','t','y','a','e','l','f','n' '),ncol = 3)

microbenchmark(bartek(matrix),Joe(matrix),James(matrix))
单位:微秒
expr min lq平均值uq max neval
bartek )50.273 55.2595 60.78952 59.4390 62.438 134.880 100
乔(矩阵)167.431 176.6170 188.46908 182.8260 192.646 337.717 100
詹姆斯(矩阵)321.313 334.3350 346.15230 339.7235 348.565 447.115 100


矩阵矩阵(1:10000,ncol = 100)
微基准(bartek(矩阵),乔(矩阵),詹姆斯(矩阵))
单位:微秒
expr min lq mean中位数uq max neval
bartek(矩阵)314.385 326.752 336.1194 331.936 337.9805 423.323 100
Joe(矩阵)2168.141 2221.477 2460.1002 2257.439 2298.4400 8856.482 100
詹姆斯(矩阵)1200.572 1250.354 1407.5943 1276.307 1323.8845 7419.931 100


I'm trying to paste all possible characters that are arranged in any diagonal within an N * N matrix.

For example, consider the following 3 X 3 matrix:

#Create matrix, convert to character dataframe
matrix <- matrix(data=c('s','t','y','a','e','l','f','n','e'),nrow=3,ncol=3)
matrix <- as.data.frame(matrix)
for(i in 1:length(colnames(matrix))){
  matrix[,i] <- as.character(matrix[,i])
}

In the matrix above I need to paste the diagonals: "see","fey", "ees", and "yef". I can find these in the dataframe with the following code:

diag <- paste(matrix[1,1],matrix[2,2],matrix[3,3],sep='')
diag1 <- paste(matrix[1,3],matrix[2,2],matrix[3,1],sep='')
diag2 <- paste(matrix[3,1],matrix[2,2],matrix[1,3],sep='')
diag3 <- paste(matrix[3,3],matrix[2,2],matrix[1,1],sep='')

The problem is that I want to automate this so that it will work on any N x N matrix. (I'm writing a function to find the diagonals in any N X N matrix). Is there an efficient way to do this?

解决方案

Oh, that's easy if you use matrix instead of data.frame :) We can choose matrix elements just like we can take vector elements:

matrix[1:3] # First three elements == first column

n <- ncol(matrix)
(1:n-1)*n+1:n
## [1] 1 5 9
(1:n-1)*n+n:1
## [1] 3 5 7

So now we can use this:

matrix[(1:n-1)*n+1:n]
[1] "s" "e" "e"
paste0(matrix[(1:n-1)*n+1:n],collapse="")
[1] "see"

And if you want it backwards, just reverse the vector of indexes using rev function:

paste0(matrix[rev((1:n-1)*n+1:n)],collapse="")
[1] "ees"

Some benchmarks:

rotate <- function(x) t(apply(x, 2, rev))
revMat <- function(mat, dir=0){
    x <- if(bitwAnd(dir,1)) rev(seq(nrow(mat))) else seq(nrow(mat))
    y <- if(bitwAnd(dir,2)) rev(seq(ncol(mat))) else seq(nrow(mat))
    mat[x,y]
}

bartek <- function(matrix){
    n <- ncol(matrix)
    c(paste0(matrix[(1:n-1)*n+1:n],collapse=""), paste0(matrix[rev((1:n-1)*n+1:n)],collapse=""),
      paste0(matrix[(1:n-1)*n+n:1],collapse=""), paste0(matrix[rev((1:n-1)*n+n:1)],collapse=""))
}

Joe <- function(matrix){
    diag0 <- diag(matrix)
    diag1 <- diag(rotate(matrix))
    diag2 <- rev(diag0)
    diag3 <- rev(diag1)
    c(paste(diag0, collapse = ""),paste(diag1, collapse = ""),
      paste(diag2, collapse = ""),paste(diag3, collapse = ""))
}

James <- function(mat){
    sapply(0:3,function(x) paste(diag(revMat(mat,x)),collapse=""))
}

matrix <- matrix(c('s','t','y','a','e','l','f','n','e'), ncol = 3)

microbenchmark(bartek(matrix), Joe(matrix), James(matrix))
Unit: microseconds
           expr     min       lq      mean   median      uq     max neval
 bartek(matrix)  50.273  55.2595  60.78952  59.4390  62.438 134.880   100
    Joe(matrix) 167.431 176.6170 188.46908 182.8260 192.646 337.717   100
  James(matrix) 321.313 334.3350 346.15230 339.7235 348.565 447.115   100


matrix <- matrix(1:10000, ncol=100)
microbenchmark(bartek(matrix), Joe(matrix), James(matrix))
Unit: microseconds
           expr      min       lq      mean   median        uq      max neval
 bartek(matrix)  314.385  326.752  336.1194  331.936  337.9805  423.323   100
    Joe(matrix) 2168.141 2221.477 2460.1002 2257.439 2298.4400 8856.482   100
  James(matrix) 1200.572 1250.354 1407.5943 1276.307 1323.8845 7419.931   100

这篇关于粘贴n * n矩阵或数据框的所有可能的对角线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆