2017-03-17 7 views
0

私は、最も近い座標に座標をバケットしようとしています。ある意味では、私は1222セントロイドでクラスタ化するkmeansを1回繰り返しています。下に私はこれを、不完全に、そしてあまりにもゆっくりと行う機能を持っています。私はこの機能を改善する上で助けを探しています:私の実際のx_locとy_locファイルは〜60000点の座標でRでは、浮動小数点座標を最も近い座標に離散化する

> dput(head(x_loc, n = 50)) 
c(13.57165, 13.61702, 13.66478, 13.70833, 13.75272, 13.7946, 
13.83851, 13.86792, 13.8973, 13.93906, 13.98099, 14.02396, 14.06338, 
14.10872, 14.15412, 14.2015, 14.26116, 14.30871, 14.35056, 14.39536, 
14.43964, 14.48442, 14.5324, 14.57675, 14.62267, 14.66972, 14.71443, 
14.75383, 14.79012, 14.82455, 14.85587, 14.87557, 14.90737, 14.9446, 
14.97763, 15.01079, 15.04086, 15.06752, 15.09516, 15.12394, 15.15191, 
15.18061, 15.20413, 15.22896, 15.25411, 15.28108, 15.3077, 15.33578, 
15.36507, 15.39272) 

> dput(head(y_loc, n = 50)) 
c(25.18298, 25.17431, 25.17784, 25.18865, 25.20188, 25.22865, 
25.26254, 25.22778, 25.20162, 25.25191, 25.3044, 25.35787, 25.40347, 
25.46049, 25.5199, 25.57132, 25.6773, 25.69842, 25.73877, 25.78383, 
25.82168, 25.86067, 25.89984, 25.93067, 25.96943, 26.01083, 26.05861, 
26.11965, 26.18428, 26.25347, 26.3352, 26.35756, 26.4682, 26.55412, 
26.63745, 26.72157, 26.80021, 26.8691, 26.93522, 26.98879, 27.03783, 
27.07818, 27.03786, 26.9909, 26.93697, 26.87916, 26.81606, 26.74908, 
26.67815, 26.60898) 

、そして私が持っている:ここでは

discretizeCourt <- function(x_loc, y_loc) { 

    # create the dataframe of points that I want to round coordinates to 
    y <- seq(0, 50, by = 2) 
    x1 <- seq(1, 93, by = 2) 
    x2 <- seq(2, 94, by = 2) 
    x <- c(x1, x2) 

    coordinates <- data.frame(
    x = rep(x, 13), 
    y = rep(y, each = length(x1)), 
    count = 0 
) 

    # loop over each point in x_loc and y_loc 
    # increment the count column whenever a point is 'near' that column  
    for(i in 1:length(x_loc)) { 
    this_x = x_loc[i] 
    this_y = y_loc[i] 

    coordinates[coordinates$x > this_x-1 & 
       coordinates$x < this_x+1 & 
       coordinates$y > this_y-1 & 
       coordinates$y < this_y+1, ]$count = 
     coordinates[coordinates$x > this_x-1 & 
        coordinates$x < this_x+1 & 
        coordinates$y > this_y-1 & 
        coordinates$y < this_y+1, ]$count + 1 
    } 
} 

は、私が働いているいくつかのテストデータであり、 〜60000の座標でそれぞれ数千のファイルがありますので、多くの作業が必要です。関数が遅く実行される理由は、私がインデックスを作成/増分する方法であることはかなり確信しています。

カウントが不完全です。技術的に優れたアプローチは、すべての60000ポイント(この例では50ポイント以上)をループし、各ポイントについて、そのポイントと座標データフレーム(1222ポイント)の各ポイント間の距離を計算することです。しかし、それはあまりにも高すぎるポイントのこの1つのセットのための60000 * 1222計算、thats。

大変ありがとうございます。 ありがとう、

EDIT:私のデータフレーム/ベクトルを2つの行列に変換し、全体のアプローチをベクトル化して、動作するかどうかを知らせます。

答えて

1

解決策よりも速く行列を処理する場合は、data.tableライブラリを使用することを検討してください。下記の例をご覧ください:

df <- data.table(x_loc, y_loc) # Your data.frame is turned into a data.table 
df$row.idx <- 1:nrow(df) # This column is used as ID for each sample point. 

ここで、各ポイントの正しい座標を見つけることができます。後で、特定の座標に属するポイントの数を計算することができます。我々は最初coordinatesデータフレームを保つ:今

y <- seq(0, 50, by = 2) 
x1 <- seq(1, 93, by = 2) 
x2 <- seq(2, 94, by = 2) 
x <- c(x1, x2) 

coordinates <- data.frame(
    x = rep(x, 13), 
    y = rep(y, each = length(x1)), 
    count = 0 
) 
coordinates$row <- 1:nrow(coordinates) # Similar to yours. However, this time we are interested in seeing which points belong to this coordinate. 

、我々は、座標をチェックし、問題点の一つの単位距離内のいずれかを返す関数を定義します。各点の

f <- function(this_x, this_y, coordinates) { 
    res <- coordinates[coordinates$x > this_x-1 & 
          coordinates$x < this_x+1 & 
          coordinates$y > this_y-1 & 
          coordinates$y < this_y+1, ]$row 
    res 
} 

、我々はその右の座標を見つける:(x_loc, y_loc, coordinate.idx)

df[, coordinate.idx := f(x_loc, y_loc), by = row.idx] 
df[, row.idx := NULL] 

dfは、以下の変数が含まれています。これを使用してcoordinates$countを入力できます。 60000ポイントであっても、1秒以上かかることはありません。

for(i in 1:nrow(coordinates)) { 
    coordinates$count = length(which(df$coordinate.idx == i)) 
} 
関連する問題