Дихотомическая разреженная матрица - PullRequest
4 голосов
/ 21 июня 2011

У меня большая разреженная матрица 500x53380 и я пытаюсь ее дихотомизировать.Я попытался использовать «event2dichot» в пакете sna, но безуспешно, потому что для этого требуется матрица смежности или сетевой объект.

Я также пытался написать простой алгоритм, такой как

for ( i in 1:500)
for (j in 1:53380)
if (matrix[i,j]>0) matrix[i,j]=1

, похоже, он работает, но поскольку матрица очень большая, она занимает часы, по крайней мере, несколько часов, и довычисления, как я задаю этот вопрос для помощи!

Знаете ли вы лучший метод или хак для выполнения этой задачи?

спасибо всем.

Ответы [ 4 ]

3 голосов
/ 21 июня 2011

Хотя ваш вопрос касается разреженных матриц, мне кажется, ваш код на самом деле описывает стандартную матрицу.

Если это так, вы можете обработать матрицу 500x53380 за считанные секунды.Следующий код использует тот факт, что матрица внутренне хранится в R как вектор.Это означает, что вы можете применить одну векторную функцию по всей матрице.Предостережение заключается в том, что вам необходимо восстановить размеры матрицы впоследствии.

Вот иллюстрация с гораздо меньшей матрицей:

mr <- 5
mc <- 8

mat <- matrix(round(rnorm(mr*mc), 3), nrow=mr)
mat

       [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]
[1,] -1.477  1.773  1.630 -0.152  1.054  0.057 -1.260  0.999
[2,] -1.863 -0.312 -0.221 -0.102  0.892 -1.255  0.996 -0.193
[3,] -0.364 -0.059  2.317  1.156  0.893  0.225  0.392 -1.986
[4,] -1.123 -0.661  0.070  0.032  0.019 -1.763 -0.205  0.951
[5,] -0.111 -3.112 -0.970 -0.794 -1.372 -0.119  1.291 -0.680

mydim <- dim(mat)
mat[mat>0] <- 1
mat[mat<0] <- 0
dim(mat) <- mydim
mat

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    1    1    0    1    1    0    1
[2,]    0    0    0    0    1    0    1    0
[3,]    0    0    1    1    1    1    1    0
[4,]    0    0    1    1    1    0    0    1
[5,]    0    0    0    0    0    0    1    0

Повторение всего этого процесса для матрицы 500x53380 занимает ~ 12 секундна моей машине:

mr <- 500
mc <- 53380

system.time({
  mat <- matrix(round(rnorm(mr*mc), 3), nrow=mr)
  mydim <- dim(mat)
  mat[mat>0] <- 1
  mat[mat<0] <- 0
  dim(mat) <- mydim
})

   user  system elapsed 
  12.25    0.42   12.88 
2 голосов
/ 21 июня 2011

Если вы используете пакет Matrix, а матрица - скажем, Mat, то вы можете оперировать Mat@x как вектор. Например. ix_low <- (Mat@x < threshold), then Mat@x[ix_low] = 0, Mat@x[!ix_low] = 1.

Ключ в том, что вы неправильно думаете, когда смотрите на разреженные матрицы. Типичное представление (i, j, value).

Вы только смотрите на прикосновение к вектору значений - не перебирайте больше ничего.

2 голосов
/ 21 июня 2011

Думайте векторизованно, и используйте только индексы. E.g.:

mat <- matrix(0, nrow = 500, ncol = 53380)
set.seed(7)
fill <- sample(500*53380, 10000)
mat[fill] <- sample(fill, 1:10, replace = TRUE)

можно дискретизировать, используя:

mat[mat > 0] <- 1

Что довольно быстро на моей рабочей станции:

> system.time(mat[mat > 0] <- 1)
   user  system elapsed 
  1.680   0.166   1.875
0 голосов
/ 08 августа 2012

Простой способ использования формально определенной разреженной матрицы (т. Е. Матрицы, сгенерированной в базе 'Matrix' с заглавной буквы M вместо более старой базы 'matrix') состоит в приведении матрицы к логическойиспользуя команду as, затем вернитесь к числовой или целочисленной матрице.

...