Trabajando con Arrays Dispersas en Programación R

Las arrays dispersas son una colección de elementos escasamente poblada, donde hay una cantidad muy inferior de elementos no nulos. El almacenamiento de datos escasamente poblados en una array completamente densa conduce a una mayor complejidad de tiempo y espacio. Por lo tanto, las estructuras de datos están optimizadas para almacenar estos datos de manera mucho más eficiente y disminuir el tiempo de acceso de los elementos.

Creación de una array dispersa

R tiene un paquete «array» incorporado que proporciona clases para la creación y el trabajo con arrays dispersas.

library(Matrix)

El siguiente fragmento de código ilustra el uso de la biblioteca de arrays:

R

# installing the matrix library 
library('Matrix')
  
# declaring matrix of 1000 rows and 1000 cols
mat1 <- Matrix(0, nrow = 1000, 
                  ncol = 1000, 
                  sparse = TRUE)
  
# setting the value at 1st row 
# and 1st col to be 1
mat1[1][1]<-5
  
print ("Size of sparse mat1")
print (object.size(mat1))

Producción:

[1] "Size of sparse mat1"
5440 bytes

El espacio ocupado por la array dispersa disminuye en gran medida, porque ahorra espacio solo para los valores distintos de cero.

Construcción de arrays dispersas a partir de densas

La array densa se puede crear simplemente con el comando matrix() incorporado en R. La array densa se alimenta luego como entrada a la función as() que está incrustada implícitamente en R. La función tiene la siguiente firma:

Sintaxis: as(array_densa, tipo = )

Parámetros:

dense_matrix : una array numérica o lógica.

type : El valor predeterminado se evalúa como dgCMatrix, en caso de que mencionemos sparseMatrix. Esto convierte la array al formato de columna dispersa comprimida (CSC). El otro tipo disponible es dgRMatrix, que convierte la array densa en formato de fila dispersa.

El siguiente fragmento de código indica la conversión de la array densa a dispersa: 

R

library(Matrix)
  
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 6, 7), 
  prob = c(0.8, 0.1, 0.1), 
  size = rows * cols, 
  replace = TRUE
)
  
dense_mat <- matrix(vals, nrow = rows)
print("Dense Matrix")
print(dense_mat)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, 
                "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)

Producción:

[1] "Dense Matrix"
    [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    7    6    0    0    0    0
[2,]    0    0    0    0    0    6
[3,]    0    7    0    0    6    0
[4,]    0    6    0    0    0    0
[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"
               
[1,] 7 6 . . . .
[2,] . . . . . 6
[3,] . 7 . . 6 .
[4,] . 6 . . . .

Operaciones en arrays dispersas

Se pueden realizar varias operaciones aritméticas y vinculantes en arrays dispersas:

Suma y resta por valor escalar

Los valores escalares se suman o restan a todos los elementos de la array dispersa. La array resultante es una array densa ya que todos los elementos operan sobre el valor escalar. El siguiente código indica el uso de los operadores + o –:

R

# Loading Library
library(Matrix)
  
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
   
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 10), 
  prob = c(0.85, 0.15), 
  size = rows * cols, 
  replace = TRUE
)
dense_mat <- matrix(vals, nrow = rows)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)
print("Addition")
  
# adding a scalar value 5 
# to the sparse matrix 
print(sparse_mat + 5)
print("Subtraction")
  
# subtracting a scalar value 1 
# to the sparse matrix 
print(sparse_mat - 1)

Producción:

[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"
                   
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[1] "Addition"
4 x 6 Matrix of class "dgeMatrix"
    [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   15   15    5    5    5    5
[2,]    5    5    5    5    5   15
[3,]    5   15    5    5   15    5
[4,]    5   15    5    5    5    5
[1] "Subtraction"
4 x 6 Matrix of class "dgeMatrix"
    [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    9    9   -1   -1   -1   -1
[2,]   -1   -1   -1   -1   -1    9
[3,]   -1    9   -1   -1    9   -1
[4,]   -1    9   -1   -1   -1   -1

Multiplicación o División por Escalar

Estas operaciones se realizan sobre todos los elementos distintos de cero de la array. La array resultante es una array dispersa: 

R

# library(Matrix)
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 10), 
  prob = c(0.85, 0.15), 
  size = rows * cols, 
  replace = TRUE
)
dense_mat <- matrix(vals, nrow = rows)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)
print("Multiplication")
  
# multiplying a scalar value 10 
# to the sparse matrix 
print(sparse_mat * 10)
print("Division")
  
# dividing a scalar value 10
# to the sparse matrix 
print(sparse_mat / 10)

Producción:

[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"
                   
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[1] "Multiplication"
4 x 6 sparse Matrix of class "dgCMatrix"
                       
[1,] 100 100 . .   .   .
[2,]   .   . . .   . 100
[3,]   . 100 . . 100   .
[4,]   . 100 . .   .   .
[1] "Division"
4 x 6 sparse Matrix of class "dgCMatrix"
               
[1,] 1 1 . . . .
[2,] . . . . . 1
[3,] . 1 . . 1 .
[4,] . 1 . . . .

Multiplicación de arrays

Las arrays se pueden multiplicar entre sí, independientemente de si son escasas o densas. Sin embargo, las columnas de la primera array deben ser iguales a las filas de la segunda.

R

library(Matrix)
  
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 10), 
  prob = c(0.85, 0.15), 
  size = rows * cols, 
  replace = TRUE
)
dense_mat <- matrix(vals, nrow = rows)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)
  
# computing transpose of matrix 
transpose_mat = t(sparse_mat)
  
# computing multiplication of matrix
# and its transpose
mul_mat = sparse_mat %*% transpose_mat
print("Multiplication of Matrices")
print(mul_mat)

Producción:

[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"                  
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[1] "Multiplication of Matrices"
4 x 4 sparse Matrix of class "dgCMatrix"
                   
[1,] 200   . 100 100
[2,]   . 100   .   .
[3,] 100   . 200 100
[4,] 100   . 100 100

Multiplicación por un vector

Las arrays se pueden multiplicar por vectores unidimensionales para transformar datos. Las filas se multiplican por los elementos correspondientes del vector, es decir, la primera fila se multiplica por el primer elemento indexado del vector, hasta la longitud del vector.

R

library(Matrix)
  
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 10), 
  prob = c(0.85, 0.15), 
  size = rows * cols, 
  replace = TRUE
)
dense_mat <- matrix(vals, nrow = rows)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)
  
# declaring a vector 
vec <- c(3, 2)
print("Multiplication by vector")
print(sparse_mat * vec)

Producción:

[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"                  
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[1] "Multiplication by vector"
4 x 6 sparse Matrix of class "dgCMatrix"
                   
[1,] 30 30 . .  .  .
[2,]  .  . . .  . 20
[3,]  . 30 . . 30  .
[4,]  . 20 . .  .  .

Combinación de Arrays

Las arrays se pueden combinar con vectores u otras arrays usando operaciones de enlace de columna cbind() o de enlace de fila rbind() . Las filas de arrays resultantes son la suma de las filas de las arrays de entrada en la función rbind() y las columnas son la suma de las columnas de las arrays de entrada en cbind() .

R

library(Matrix)
  
# construct a matrix with values
#   0 with probability 0.80
#   6 with probability 0.10
#   7 with probability 0.10
set.seed(0)
rows <- 4L
cols <- 6L
vals <- sample(
  x = c(0, 10), 
  prob = c(0.85, 0.15), 
  size = rows * cols, 
  replace = TRUE
)
dense_mat <- matrix(vals, nrow = rows)
  
# Convert to sparse 
sparse_mat <- as(dense_mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)
  
# combining matrix through rows
row_bind <- rbind(sparse_mat,
                  sparse_mat)
  
# printing matrix after row bind
print ("Row Bind")
print (row_bind)

Producción:

[1] "Sparse Matrix"
4 x 6 sparse Matrix of class "dgCMatrix"
                   
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[1] "Row Bind"
8 x 6 sparse Matrix of class "dgCMatrix"
                   
[1,] 10 10 . .  .  .
[2,]  .  . . .  . 10
[3,]  . 10 . . 10  .
[4,]  . 10 . .  .  .
[5,] 10 10 . .  .  .
[6,]  .  . . .  . 10
[7,]  . 10 . . 10  .
[8,]  . 10 . .  .  .

Propiedades de arrays dispersas

  • Valores
    NA Los valores NA no se consideran equivalentes a la escasez y, por lo tanto, se tratan como valores distintos de cero. Sin embargo, no participan en ninguna operación de array dispersa.

R

library(Matrix)
  
# declaring original matrix 
mat <- matrix(data = c(5.5, 0, NA, 
                         0, 0, NA), nrow = 3)
print("Original Matrix")
print(mat)
sparse_mat <- as(mat, "sparseMatrix")
print("Sparse Matrix")
print(sparse_mat)

Producción:

[1] "Original Matrix"
    [,1] [,2]
[1,]  5.5    0
[2,]  0.0    0
[3,]   NA   NA
[1] "Sparse Matrix"
3 x 2 sparse Matrix of class "dgCMatrix"
         
[1,] 5.5  .
[2,] .    .
[3,]  NA NA

  • Los datos de array dispersos se pueden escribir en un archivo ordinario en MatrixMarketformat (.mtx). La función WriteMM está disponible para transferir los datos de una array dispersa a un archivo.
writeMM(obj-matrix,file="fname.mtx")

Publicación traducida automáticamente

Artículo escrito por yashchuahan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *