Mam dużą matrycę (m) i chcę zastąpić wartości w matrycy (m), które pasują do wartości przechowywanych w wektorach (wartości_to_bebe_placed) przez nowe wartości (New_values). My Wektory są sami przechowywane w dataframe, więc mogę pętla nad dataframe, aby uzyskać wektory, a następnie sprawdzić, czy wartości macierzy są zawarte w wektory. Poniższy kod robi to, co ma zrobić, ale jest to zbyt wolno dla moich danych wejściowych. Moje oryginalne dane to macierzy z 4600 rzędami i 5900 kolumnami, a największe z moich 750 wektorów zawiera> 6 milionów numerów do porównania.

Myślę, że istnieje bardziej skuteczny sposób, aby to zrobić i przyspieszyć czas obliczeniowy. Czy ktoś może pomóc mi to zrozumieć? (Mam dużo -9999 wartości w mojej matrycy, więc pomijanie ich może poprawić czas obliczeniowy, ale prawdopodobnie nie wystarczy)

Oto przykład napisany w 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
}
1
albren 14 marzec 2020, 14:42

2 odpowiedzi

Najlepsza odpowiedź

W r możesz po prostu wywołać elementy pasujące, zamiast go iterniować przez nich:

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
StupidWolf 14 marzec 2020, 18:06

Nie wiem, w jakim języku jest to, ale z sytuacji, którą opisałeś, może być bardziej wydajny, aby zbudować tabelę do wyszukiwania wstecznego, który mapuje od wartości do "komórek" w matrycy, a następnie użyj tej tabeli, aby znaleźć Komórki, które muszą zostać zaktualizowane (zamiast zapętlić się z nimi wiele razy).

Jeśli twój język lub jego standardowa biblioteka ma wbudowaną implementację czegoś takiego jak mapa hashtable / Hash, użyj tego.

Po zaktualizowaniu komórki w matrycy, ponieważ pasuje do jednej z "wartości do wymiany", może być aktualizowany po raz drugi, ponieważ wartość nowa pasuje do innej "wartość do wymiany"? Jeśli tak, musisz zaktualizować tabelę wyszukiwania wstecznego w tym samym czasie, gdy aktualizujesz rzeczywistą matrycę, w przeciwnym razie będziesz miał błędy.

Możliwe jest wstępne przetwarzanie wektorów "Wartości do wymiany", aby uniknąć tej sytuacji, tak że gdy po zbudowaniu tabeli wyszukiwania wstecznego można go użyć dla całego procesu bez aktualizacji. Następnie wyrzuć go na końcu (po wykonaniu wszystkich zamienników). Jednakże, uzyskanie tego prawa w prawo będzie nieznacznie trudniejsze niż wraz z aktualizacją tabeli wyszukiwania wstecznego wraz z matrycą.

0
Alex D 14 marzec 2020, 14:22