Эффективный способ замены значений в матрице (R) - PullRequest
1 голос
/ 14 марта 2020

У меня большая матрица (m), и я хочу заменить значения в матрице (m), которые соответствуют значениям, хранящимся в векторах (values_to_be_replaced), новыми значениями (new_values). Мои векторы сами хранятся в фрейме данных, поэтому я могу l oop на фрейме данных получить векторы, а затем проверить, содержатся ли значения матриц в векторах. Код ниже делает то, что должен, но он слишком медленный для моих входных данных. Мои исходные данные - это матрица с 4600 строками и 5900 столбцами, а самый большой из моих 750 векторов содержит> 6 миллионов чисел для сравнения.

Я думаю, есть более эффективный способ сделать это и ускорить время вычислений. Может кто-нибудь помочь мне разобраться? (У меня много значений -9999 в моей матрице, поэтому их пропуск может сократить время вычислений, но, вероятно, этого недостаточно)

Вот пример, написанный на R:

library("dplyr")
## setting up the input dataframe
df<-setNames(data.frame(matrix(ncol = 4, nrow = 50)), c("ids", "var1", "var2", "var3"))
df$ids<-seq(1, 50,1)
df$var1<-rep(c(2, 4, 2, 1, 3, 5,1, 1,1, 6), each = 5)
df$var2<-rep(c(2, 4, 2, 1, 3, 5,1, 1,1, 6), each = 5)
df$var3<-rep(c(2, 4, 2, 1, 3, 5,1, 1,1, 6), each = 5)

##summarizing it by variables and ids
df<-df%>%
  group_by(var1, var2, var3)%>%
  summarise(ids=toString(ids))%>%data.frame()

##giving a new value by which values in matrix should be replaced
df$new_values<-c("101", "102", "103", "104", "105", "106")

##setting up a matrix
m = matrix( c(16, -9999,17, -9999, 18), nrow=5,  ncol=10, byrow = TRUE)        # fill matrix by rows 

##looping over dataframe
y<-0
for (i in 1:length(df$ids)) {
  values_to_be_replaced<-strsplit(df$ids[i], ",")
  values_to_be_replaced<-unlist(values_to_be_replaced, use.names=FALSE)
  values_to_be_replaced<-gsub(" ", "", values_to_be_replaced, fixed = TRUE)
  print(values_to_be_replaced)
  print(i)
  #print(length(values_to_be_replaced))
  m<-apply(m, 1:2, function(x) ifelse(x %in% values_to_be_replaced, df$new_values[i], x))
  #print(values_to_be_replaced)
  y<-y+1
}

Ответы [ 2 ]

0 голосов
/ 14 марта 2020

В R вы можете просто вызывать совпадающие элементы, вместо того, чтобы выполнять их итерацию:

for (i in 1:length(df$ids)) {
  values_to_be_replaced<-strsplit(gsub(" ","",df$ids[i]), ",")[[1]]
  values_to_be_replaced<-as.numeric(values_to_be_replaced)
  m[m %in% values_to_be_replaced] <- df$new_values[i]
}
0 голосов
/ 14 марта 2020

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

Если ваш язык или его стандартная библиотека имеет встроенную реализацию чего-то вроде хеш-таблицы / ha sh используйте карту.

После обновления ячейки в матрице, поскольку она соответствует одному из «значений, подлежащих замене», можно ли его обновить во второй раз, поскольку значение new соответствует другому «значению для замены»? Если это так, вам придется обновлять таблицу обратного просмотра одновременно с обновлением фактической матрицы, в противном случае у вас будут ошибки.

Возможно предварительно обработать векторы «значений, подлежащих замене» чтобы избежать этой ситуации, чтобы после того, как вы создадите таблицу обратного просмотра, вы сможете использовать ее для всего процесса, не обновляя ее. Затем просто отмените его в конце (после того, как вы сделали все замены). Однако получить правильный код будет немного сложнее, чем просто обновить таблицу обратного просмотра вместе с матрицей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...