如何填充对角线并忽略R中矩阵的对角线?

时间:2019-10-22 15:35:29

标签: r matrix

我正在尝试在R中填充矩阵,最终结果将忽略对角线条目,并且值将填充在对角线周围。我的意思的简单示例是,如果我采用一个简单的3x3矩阵,如下所示:

ab <- c(1:9)
mat <- matrix(ab,nrow=3,ncol=3)
colnames(mat)<- paste0("x", 1:3)
rownames(mat)<- paste0("y", 1:3)
mat

    x1 x2 x3
y1  1  4  7
y2  2  5  8
y3  3  6  9

我想要实现的是用0填充对角线,并将所有其他值绕对角线移动。因此,例如,如果我只使用diag(mat)<-0,结果如下:

   x1 x2 x3
y1  0  4  7
y2  2  0  8
y3  3  6  0

鉴于此,我正在寻找的结果是这样的(其中值缠绕在对角线上):

   x1 x2 x3
y1  0  3  5
y2  1  0  6
y3  2  4  0

我不担心从矩阵中推出的值(即7,8,9)。

有什么建议吗?

谢谢

编辑:下面被推荐的解决方案似乎已经解决了问题

3 个答案:

答案 0 :(得分:4)

适用于您的示例的一种解决方案是,首先声明一个矩阵,该矩阵除对角线外都充满一个矩阵:

import numpy as np
def initialize_parameters(n_x, n_h, n_y):

    np.random.seed(2) # we set up a seed so that our output matches ours although the initialization is random.

    W1 = np.random.randn(n_h, n_x) * 0.01 #weight matrix of shape (n_h, n_x)
    b1 = np.zeros(shape=(n_h, 1))  #bias vector of shape (n_h, 1)
    W2 = np.random.randn(n_y, n_h) * 0.01   #weight matrix of shape (n_y, n_h)
    b2 = np.zeros(shape=(n_y, 1))  #bias vector of shape (n_y, 1)

    #store parameters into a dictionary    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    return parameters

#Function to define the size of the layer
def layer_sizes(X, Y):
    n_x = X.shape[0] # size of input layer
    n_h = 6# size of hidden layer
    n_y = Y.shape[0] # size of output layer
    return (n_x, n_h, n_y)

然后用所需的非对角线值替换所有

<a href="#" onclick="removeNumber()">

更复杂的情况(例如对角系数不为0或对角线元素的数量未知)可能需要一点点附加工作。

答案 1 :(得分:0)

您可能需要循环:

n <- 9
seqs <- seq(1:n)
mats <- matrix(0, nrow = 3, ncol = 3)
ind <- 0
for(i in 1:nrow(mats)){
     for(j in 1:nrow(mats)){

         if(i == j) {
             mats[i,j] <- 0 }
             else {
                 ind <- ind + 1
                 mats[j,i] <- seqs[ind]
             }
         }
     }

结果:

>mats
     [,1] [,2] [,3]
[1,]    0    3    5
[2,]    1    0    6
[3,]    2    4    0

答案 2 :(得分:0)

对于您的示例,这可以正常工作。不确定我是否需要n1n2,如果始终对称,可以将其更改为一个值

# original data
ab <- c(1:9)
n1 <- 3
n2 <- 3

# You could add the 0's to the diagonal, by adding a 0 before every n1 split
# of the data e.g. 0,1,2,3 & 0,4,5,6 & 0,7,8,9
split_ab <- split(ab, ceiling((1:length(ab))/n1))
update_split_ab <- lapply(split_ab, function(x){
  c(0, x)
}) 
new_ab <- unlist(update_split_ab)

mat <- matrix(new_ab, nrow=n1, ncol=n2)
colnames(mat)<- paste0("x", 1:n2)
rownames(mat)<- paste0("y", 1:n1)
mat

# turn this in to a function

makeShiftedMatrix <- function(ab=1:9, n1=3, n2=3){

  split_ab <- split(ab, ceiling((1:length(ab))/n1))
  update_split_ab <- lapply(split_ab, function(x){
    c(0, x)
  }) 
  new_ab <- unlist(update_split_ab)

  mat <- matrix(new_ab, nrow=n1, ncol=n2)
  colnames(mat)<- paste0("x", 1:n2)
  rownames(mat)<- paste0("y", 1:n1)
  mat
  return(mat)
}

# default
makeShiftedMatrix()

# to read in original matrix and shift:
old_mat <- matrix(ab, nrow=n1, ncol=n2)
makeShiftedMatrix(ab=unlist(old_mat))