gpt4 book ai didi

r - R中矩阵对象之间的Dist函数

转载 作者:行者123 更新时间:2023-12-03 23:33:16 25 4
gpt4 key购买 nike

我有一个非常简单的问题。

给定一个由 x 表示的 N 维点(例如,一个向量,其中每个元素代表一个维度)和一个 MxN 维矩阵(或一组具有 N 维的 M 点!)表示为y.

set.seed(999)
data <- matrix(runif(1100), nrow = 11, ncol = 10)

x <- data[1, ]
y <- data[2:nrow(data), ]

我想计算 xy 的每个点之间的距离度量。我知道这样做的一个简单方法是:

distances <- dist(rbind(x, y))

但是,我认为这对于这种特定情况不是很有效,原因如下:

  1. 我需要使用 rbind,这非常消耗内存。
  2. dist 计算每个点之间的距离,但我只对其中 10 个距离感兴趣,或者只是 x 的每个点之间的距离是。我对 y 点之间的内部距离不感兴趣。
  3. 由于 (2) 我需要手动选择 dist 矩阵的最后一行来获得我实际需要的距离。

我想到的一个可能的解决方案是通过 y 手动循环应用距离测量。

distances <- apply(y, MARGIN = 1, function(a, b = x) {
sqrt(sum((a - b)^2))
})

但是,当两种方法都计时时,我得到:

func1 <- function(x, y) {
apply(y, MARGIN = 1, function(a, b = x) {
sqrt(sum((a - b)^2))
})
}

func2 <- function(x, y) {
dist(rbind(x, y))
}

microbenchmark::microbenchmark(
func1(x, y),
func2(x, y)
)

Unit: microseconds
expr min lq mean median uq max neval
func1(x, y) 29.602 30.450 61.21791 31.301 32.3510 2916.101 100
func2(x, y) 15.101 15.801 28.55304 17.201 17.7015 1143.001 100

所以我的问题是:有没有办法比使用 dist 更快地解决这个问题?

最佳答案

一个选项是 dapply from collapse

 library(collapse)
func3 <- function(x, y) {
dapply(y, function(a, b = x) {
sqrt(sum((a-b)^2))
}, MARGIN = 1)
}

或者可以使用vapply

func4 <- function(x, y) {
vapply(seq_len(nrow(y)), function(i, b = x) sqrt(sum((y[i,]-b)^2)), numeric(1))
}

或者可以复制向量并在减去后使用 rowSums

func7 <- function(x, y) sqrt(rowSums((y-x[col(y)])^2))
microbenchmark::microbenchmark(func1(x, y), func3(x, y), func4(x, y), func7(x, y))
#Unit: microseconds
# expr min lq mean median uq max neval cld
# func1(x, y) 37.605 39.7475 61.17471 40.7595 42.1865 1955.888 100 a
# func3(x, y) 22.212 23.5945 68.63660 24.8320 25.8670 4333.933 100 a
# func4(x, y) 21.089 22.7930 24.11542 23.5945 24.2315 58.050 100 a
# func7(x, y) 7.731 8.9135 44.45935 10.0615 10.9500 3415.959 100 a

关于r - R中矩阵对象之间的Dist函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66943824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com