看板 R_Language 關於我們 聯絡資訊
require(magrittr) data(iris) set.seed(1) data <- iris[sample(nrow(iris)) ,] # 打散資料 Xtrain <- data[1:100,1:4] Xtest <- data[101:150,1:4] M <- nrow(Xtrain) N <- nrow(Xtest) distmatrix <- matrix(0,nrow = M,ncol = N) for(i in 1:M){ for(j in 1:N){ distmatrix[i,j]<- sum((Xtrain[i,]-Xtest[j,])^2) %>% sqrt() } } 最近在implement knn 的 distancematrix 想在厚臉皮的問問看 這種常見的操作要怎麼 轉成非迴圈寫法 我用迴圈寫塞的好慢喔 我自己只想到這樣 就卡住了 (matrix(rep(Xtest[1,],nrow(Xtrain)),ncol=ncol(Xtrain),byrow = T)-Xtrain)^2 %>% apply(X=. ,1,sum)%>%sqrt -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 219.91.75.186 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1585193311.A.644.html
locka: 避免把 apply 搭配 %>% pipeline 運算子 因為他會把前半部 03/26 11:38
locka: 的向量結果做完才會一個一個丟pipeline 這樣一定超慢(有錯 03/26 11:38
locka: 請指正) 03/26 11:38
VIATOR: expand.grid和apply一起用可以取代nested loop 03/26 13:28
params <- expand.grid(M=seq(M), N=seq(N)) distmatrix2 <- matrix(mapply(function(i,j) sqrt(sum((Xtrain[i,]-Xtest[j,])^2)), params$M, params$N), nrow = M, ncol = N) 有點看不懂 mapply這段 有人可以解釋一下他是怎麼運作的嗎 # EQUIVALENT TO OP's distance identical(distmatrix, distmatrix2) 老外的解法 ※ 編輯: empireisme (219.91.75.186 臺灣), 03/26/2020 14:34:27 ※ 編輯: empireisme (219.91.75.186 臺灣), 03/26/2020 14:46:28 ※ 編輯: empireisme (219.91.75.186 臺灣), 03/26/2020 14:58:34
andrew43: function(i,j)裡的i和j就是params$M和params$N 03/26 23:10
andrew43: 每做一次function都是拿M和N各一個元素 03/26 23:13
andrew43: 就此例而言,distmatrix[i, j] <- 改成 03/27 10:01
andrew43: rbind(Xtrain[i, ], Xtest[j, ]) %>% dist 會快不少。 03/27 10:01
andrew43: 或是只有一次dist硬幹 https://i.imgur.com/feLrQO1.jpg 03/27 10:28
andrew43: 小改正 https://i.imgur.com/YkTAJF4.jpg 03/27 10:31
empireisme: 謝a大,但是用dist函數不就代表不能自己定義距離的意 03/27 18:40
empireisme: 思? 03/27 18:40
andrew43: 對,但有不少距離定義在R中是由C寫成的。你看看?dist 03/27 18:43
andrew43: 中的method有沒有你想用的,其它package也有提供 03/27 18:43
andrew43: 例如生態學家常用的vegan::vegdist() 03/27 18:44
Gjerry: 我想你的寫法會比較慢可能不是用 apply 就能解決。一個一 03/28 03:02
Gjerry: 個算值然後填入矩陣,在R裡面比較沒有效率。可以考慮用矩 03/28 03:02
Gjerry: 陣運算,一次計算完整個 row 再填入矩陣,會會很多。 03/28 03:02
empireisme: 矩陣運算我就是有點卡住 03/28 19:30
andrew43: 針對矩陣運算,例如,不要一列對一列算,而是改成一矩 03/28 20:56
andrew43: 陣對一矩陣算。技巧是你需要額外先造出一堆以列重複的 03/28 20:56
andrew43: 矩陣使得二個矩陣大小相等而可以直接相減,於是迴圈只 03/28 20:56
andrew43: 剩一層。效果如何待測試。若有興趣歡迎繼續發文討論。 03/28 20:56
empireisme: 其實我有做到那邊,在本文的最後一段 03/29 00:42
empireisme: 但是那時候想說還是有一層迴圈就沒繼續做了 03/29 00:42
andrew43: 一樣的,你可以創造出兩個非常多重複列但重複方式不同 03/29 01:22
andrew43: 的大矩陣以達成所以的對應情況,於是完全不用迴圈了。 03/29 01:22
andrew43: 技巧上可用rep產生不同的重複列號索引來生成二個大矩陣 03/29 01:27
andrew43: 。 03/29 01:27
empireisme: ok 03/30 13:57
Gjerry: 也許可以這樣寫,在我電腦上其實用 for 的function比較快 03/30 14:55
Gjerry: https://imgur.com/5UZT7m3.jpg 03/30 14:55
andrew43: 抱歉前一大段手邊沒電腦,現在補上 03/30 16:51
andrew43: https://ideone.com/zlHh25 03/30 16:51
empireisme: 大神們感恩! 03/30 20:53