1

2 つの座標セットがあり、最も近い座標の一致を見つけようとしています。1 つのデータセットが 100 万件のレコードで構成され、もう 1 つのデータセットが 50 万件近くのレコードで構成されている場合、このタスクを実行するためのより良い方法を探しており、提案が必要です。

最初のデータセットの出力は

structure(list(longitude = c(-2.5168477762, -2.5972432832, -2.5936692407, 
-2.5943475677, -2.5923214528, -2.5919014869, -2.5913454553, -2.5835739992, 
-2.5673150195, -2.5683356381), latitude = c(51.4844052488, 51.45278562, 
51.4978889752, 51.4979844501, 51.4983813479, 51.4982126232, 51.4964350456, 
51.4123728037, 51.4266239227, 51.4265740193)), .Names = c("longitude", 
"latitude"), row.names = c(NA, 10L), class = "data.frame")

2番目のデータセットのdputは

structure(list(longitude = c(-3.4385392589, -3.4690321528, -3.2723981534, 
-3.3684012246, -3.329625956, -3.3093349806, 0.8718409198, 0.8718563602, 
0.8643998472, 0.8644153057), latitude = c(51.1931124311, 51.206897181, 
51.1271423704, 51.1618047221, 51.1805971356, 51.1663567178, 52.896084336, 
52.896092955, 52.9496082626, 52.9496168824)), .Names = c("longitude", 
"latitude"), row.names = 426608:426617, class = "data.frame")

R で approx および findInterval 関数を見てきましたが、それらがどのように機能するかについて完全には理解していませんでした。私がやろうとしているのは、dataset1 から座標を取得し、dataset2 のすべての座標と一致させて、最も近い一致を見つけることです。現在、私は 2 つの forloops を使用していますが、データのサイズが原因で永遠に時間がかかります。

私が試したコードを以下に示します。

cns <- function(x,y)
{
 a = NULL
 b = NULL

for(i=1:nrow(x))  
{
  for(j=1:nrow(y)) 
  { 
      a[j]  = distm(c(x$longitude[i],x$latitude[i]),
                c(y$longitude[j],y$latitude[j]),
                fun = distVincentyEllipsoid)

  } 
  b[i] = which(a == min(a))
}
  return(y[b,])
}

上記の関数は、dataset1 から 1 つのポイントを取得し、dataset2 のすべてのポイントを使用して距離を計算し、最小距離を見つけて、その距離の座標を返します。

このタスクを適切な時間で達成するための並列処理を探しています。どんな提案でも大歓迎です。

よろしく、

4

1 に答える 1

2

1. コードをベクトル化してみる

ベクトル化は、多くの場合、for ループよりも R の方が効率的です。

  cns2 <- function(x,y){
  b <- numeric(length(nrow(y)))
  for(i in 1:nrow(x)){
    a<- distm(x=x[i,],
                    y=y,
                    fun = distVincentyEllipsoid)

       b[i] = which.min(a)
    }
   return(y[b,])
  }  

違いを評価しましょう:

library(microbenchmark)
microbenchmark(cns(x,y), ###where x is your first dataframe, y the second
               cns2(x,y)
               )

結果:

  Unit: milliseconds
       expr      min       lq     mean   median       uq      max neval
  cns(x, y) 42.46518 45.16829 46.61517 46.45560 47.09023 80.25171   100
 cns2(x, y) 26.09484 27.33122 28.21505 28.07837 29.10225 30.74004   100

並列計算を行わなくても、すでに半分の時間に短縮されています。もっと増やすことはできますか?

cns3 <- function(x,y){
  b <- numeric(length = nrow(y))

  a<- distm(x=x,
              y=y,
              fun = distVincentyEllipsoid)

  b<-apply(X = a,MARGIN =  1, which.min) 
  return(y[b,])
}

ベンチマークの結果:

    Unit: milliseconds
       expr      min       lq     mean   median       uq       max neval
  cns(x, y) 43.38928 45.69135 48.72223 46.70839 48.56951 135.80555   100
 cns2(x, y) 25.96674 27.15066 28.86999 28.43569 29.99138  35.86383   100
 cns3(x, y) 23.90187 24.84592 26.68738 25.87950 27.99075  34.71469   100

ということでcns3の方が少し速いようですが、cns2はforをforeachに置き換えることで簡単に並列化できます。

それが正しいか?3 つの方法で同じ出力が得られます。

> cns(x,y)
         longitude latitude
426613   -3.309335 51.16636
426613.1 -3.309335 51.16636
426613.2 -3.309335 51.16636
426613.3 -3.309335 51.16636
426613.4 -3.309335 51.16636
426613.5 -3.309335 51.16636
426613.6 -3.309335 51.16636
426613.7 -3.309335 51.16636
426613.8 -3.309335 51.16636
426613.9 -3.309335 51.16636
> cns2(x,y)
         longitude latitude
426613   -3.309335 51.16636
426613.1 -3.309335 51.16636
426613.2 -3.309335 51.16636
426613.3 -3.309335 51.16636
426613.4 -3.309335 51.16636
426613.5 -3.309335 51.16636
426613.6 -3.309335 51.16636
426613.7 -3.309335 51.16636
426613.8 -3.309335 51.16636
426613.9 -3.309335 51.16636
> cns3(x,y)
         longitude latitude
426613   -3.309335 51.16636
426613.1 -3.309335 51.16636
426613.2 -3.309335 51.16636
426613.3 -3.309335 51.16636
426613.4 -3.309335 51.16636
426613.5 -3.309335 51.16636
426613.6 -3.309335 51.16636
426613.7 -3.309335 51.16636
426613.8 -3.309335 51.16636
426613.9 -3.309335 51.16636

2. よくあることですが、最小値を求められたとき、同点の場合はどうしますか?

あなたが書いた方法では、すべての関係を保持します。これは、 b がリスト a に強制される可能性があるため、問題になる可能性があります。

于 2016-03-31T11:28:11.110 に答える