От разреженной матрицы до фрейма данных - PullRequest
0 голосов
/ 05 октября 2018

У меня есть разреженная матрица смежности M размером 12 000 X 12 000 в R, и я хотел бы перенести ее в другое программное обеспечение.Я вынужден преобразовать его в data.frame из 3 столбцов, где col1 - это имя col моей матрицы, col2 - имя строки моей матрицы, а col3 - значение M [i, j].Я хочу создать запись в data.frame только в том случае, если M [i, j] не равно 0 (сохраняя логику разреженной матрицы).

Я видел много вопросов, спрашивающих, как это сделать.противоположное действие, так что я думаю, что это не так сложно, но я не могу найти, как это сделать эффективно.

Спасибо за вашу помощь

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Во-первых, я предполагаю, что у вас есть регулярная разреженная матрица, созданная с помощью пакета Matrix.То есть ненулевые записи кодируются с точки зрения их значений, столбцов и смещений строк.

Пакет Matrix имеет альтернативное представление разреженной матрицы в виде набора триплетов , гдененулевые значения кодируются в терминах их координат.Это в основном то, что вы хотите.Оказывается, преобразовать в эту форму легко;и затем вы можете превратить его в фрейм данных.

Одна бородавка заключается в том, что координаты начинаются с нуля (т. е. элементы в первой строке кодируются как строка 0), что вы можете или не можетехотите преобразовать в единичные.

library(Matrix)
# some sample data
m <- rsparsematrix(12000, 12000, 1e-7)

# convert to triplet form
mm <- as(m, "dgTMatrix")

# convert to data frame: convert to 1-based indexing
data.frame(i=mm@i + 1, j=mm@j + 1, x=mm@x)

#       i     j     x
#1    144   624  0.16
#2   3898  1106 -1.80
#3  11444  1395  0.89
#4   3981  2300  0.27
#5   3772  3602 -0.42
#6   2674  4058  0.79
#7   4446  4943  0.58
#8   4550  6629  0.82
#9   4125  6867 -0.86
#10  3151  7865 -0.42
#11 11590  8019 -0.96
#12  4808  9428 -1.30
#13 10453 11141  0.39
#14 11112 11592 -1.40

Если вы хотите, чтобы строка / столбец имена , а не числа:

data.frame(i=rownames(mm)[mm@i + 1], j=colnames(mm)[mm@j + 1], x=mm@x)
0 голосов
/ 05 октября 2018

Под капотом матрица - это просто вектор.Вы можете использовать which для получения векторных индексов ненулевых элементов, а затем выполнить некоторую модульную арифметику для восстановления индексов:

set.seed(123)
M <- matrix(sample(0:2,12,replace = TRUE,prob = c(0.8,0.1,0.1)),nrow = 3)
v <- which(M != 0)
rows <- 1 + (v-1) %% nrow(M)
cols <- 1 + (v-1) %/% nrow(M)
nonzeros <- data.frame(i=rows,j=cols,item=M[v])

В этом примере:

> M
     [,1] [,2] [,3] [,4]
[1,]    0    2    0    0
[2,]    0    1    2    1
[3,]    0    0    0    0
> nonzeros
  i j item
1 1 2    2
2 2 2    1
3 2 3    2
4 2 4    1
...