resueltos metodo manhattan interpretar euclidiana ejercicios distancia como cluster analisis r for-loop distance vectorization

metodo - Cómo calcular la distancia euclidiana(y guardar solo resúmenes) para grandes marcos de datos



distancia manhattan (2)

Escribí un corto ''por'' para buscar la distancia euclidiana mínima entre cada fila en un marco de datos y todas las demás filas (y para registrar qué fila está más cerca). En teoría, esto evita los errores asociados con el intento de calcular medidas de distancia para matrices muy grandes. Sin embargo, aunque no se está guardando mucho en la memoria, es muy, muy lento para las matrices grandes (mi caso de uso de ~ 150 000 filas todavía se está ejecutando).

Me pregunto si alguien puede aconsejarme o señalarme en la dirección correcta en términos de vectorizar mi función, usando aplicar o similar. Disculpas por lo que puede parecer una pregunta simple, pero todavía estoy luchando por pensar de forma vectorializada.

Gracias de antemano (y por su paciencia).

require(proxy) df<-data.frame(matrix(runif(10*10),nrow=10,ncol=10), row.names=paste("site",seq(1:10))) min.dist<-function(df) { #df for results all.min.dist<-data.frame() #set up for loop for(k in 1:nrow(df)) { #calcuate dissimilarity between each row and all other rows df.dist<-dist(df[k,],df[-k,]) # find minimum distance min.dist<-min(df.dist) # get rowname for minimum distance (id of nearest point) closest.row<-row.names(df)[-k][which.min(df.dist)] #combine outputs all.min.dist<-rbind(all.min.dist,data.frame(orig_row=row.names(df)[k], dist=min.dist, closest_row=closest.row)) } #return results return(all.min.dist) } #example min.dist(df)


Por lo general, las funciones integradas son más rápidas que la codificación usted mismo (porque están codificadas en Fortran o C / C ++ y optimizadas).

Parece que la función dist {stats} responde su pregunta en:

Descripción Esta función calcula y devuelve la matriz de distancia calculada utilizando la medida de distancia especificada para calcular las distancias entre las filas de una matriz de datos.


Este debería ser un buen comienzo. Utiliza operaciones rápidas de matriz y evita la construcción de objetos en crecimiento, ambas sugeridas en los comentarios.

min.dist <- function(df) { which.closest <- function(k, df) { d <- colSums((df[, -k] - df[, k]) ^ 2) m <- which.min(d) data.frame(orig_row = row.names(df)[k], dist = sqrt(d[m]), closest_row = row.names(df)[-k][m]) } do.call(rbind, lapply(1:nrow(df), which.closest, t(as.matrix(df)))) }

Si esto todavía es demasiado lento, como una mejora sugerida, puede calcular las distancias para k puntos a la vez en lugar de uno solo. El tamaño de k deberá ser un compromiso entre la velocidad y el uso de la memoria.

Editar: También lea https://.com/a/16670220/1201032