R - Как ускорить расчет евклидова расстояния на очень большом наборе данных

Сообщество,

У меня есть очень большой набор данных, содержащий 3 столбца с координатами (x, y, z) и 24 x 10^6 строк. Мне нужно вычислить евклидово расстояние между всеми строками и первым рядом, которое равно 0, 0, 0. С циклом ниже это занимает очень много времени! Я также попробовал это также на матрице вместо фрейма данных, но это не решило проблему.

У кого-нибудь есть предложения по ускорению этого процесса?

library(cluster)

e <- list() # list to be filled with euclidean distances

for (r in 1:(nrow(pca.123.df))) {

  eucl.dist <- daisy(pca.123.df[c(1,r), ], metric = "euclidean") # Euclidean distance between anomaly and zero (row 1)

  e[[r]] <- eucl.dist[1]

}

1 ответ

Используйте формулу для евклидова расстояния.

Воспроизводимый пример вашего кода:

library(cluster)
set.seed(42)
DF <- as.data.frame(rbind(0, matrix(rnorm(15), ncol=3))) 

e <- list() # list to be filled with euclidean distances

for (r in 1:(nrow(DF))) {

  eucl.dist <- daisy(DF[c(1,r), ], metric = "euclidean") # Euclidean distance between anomaly and zero (row 1)

  e[[r]] <- eucl.dist[1]

}
# [[1]]
# [1] 0
# 
# [[2]]
# [1] 1.895646
# 
# [[3]]
# [1] 2.79863
# 
# [[4]]
# [1] 1.438665
# 
# [[5]]
# [1] 2.133606
# 
# [[6]]
# [1] 0.4302796

Векторизованное решение:

sqrt(colSums((t(DF)-unlist(DF[1,]))^2))
#[1] 0.0000000 1.8956461 2.7986300 1.4386649 2.1336055 0.4302796

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

sqrt(rowSums(DF^2))
#1] 0.0000000 1.8956461 2.7986300 1.4386649 2.1336055 0.4302796
Другие вопросы по тегам