作者empireisme (empireisme)
看板R_Language
标题Re: [问题]不使用for改使用apply写法的可能性
时间Thu Mar 26 11:28:27 2020
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://webptt.com/cn.aspx?n=bbs/R_Language/M.1585193311.A.644.html
1F:→ locka: 避免把 apply 搭配 %>% pipeline 运算子 因为他会把前半部 03/26 11:38
2F:→ locka: 的向量结果做完才会一个一个丢pipeline 这样一定超慢(有错 03/26 11:38
3F:→ locka: 请指正) 03/26 11:38
4F:推 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
5F:推 andrew43: function(i,j)里的i和j就是params$M和params$N 03/26 23:10
6F:→ andrew43: 每做一次function都是拿M和N各一个元素 03/26 23:13
7F:→ andrew43: 就此例而言,distmatrix[i, j] <- 改成 03/27 10:01
8F:→ andrew43: rbind(Xtrain[i, ], Xtest[j, ]) %>% dist 会快不少。 03/27 10:01
11F:→ empireisme: 谢a大,但是用dist函数不就代表不能自己定义距离的意 03/27 18:40
12F:→ empireisme: 思? 03/27 18:40
13F:→ andrew43: 对,但有不少距离定义在R中是由C写成的。你看看?dist 03/27 18:43
14F:→ andrew43: 中的method有没有你想用的,其它package也有提供 03/27 18:43
15F:→ andrew43: 例如生态学家常用的vegan::vegdist() 03/27 18:44
16F:推 Gjerry: 我想你的写法会比较慢可能不是用 apply 就能解决。一个一 03/28 03:02
17F:→ Gjerry: 个算值然後填入矩阵,在R里面比较没有效率。可以考虑用矩 03/28 03:02
18F:→ Gjerry: 阵运算,一次计算完整个 row 再填入矩阵,会会很多。 03/28 03:02
19F:→ empireisme: 矩阵运算我就是有点卡住 03/28 19:30
20F:推 andrew43: 针对矩阵运算,例如,不要一列对一列算,而是改成一矩 03/28 20:56
21F:→ andrew43: 阵对一矩阵算。技巧是你需要额外先造出一堆以列重复的 03/28 20:56
22F:→ andrew43: 矩阵使得二个矩阵大小相等而可以直接相减,於是回圈只 03/28 20:56
23F:→ andrew43: 剩一层。效果如何待测试。若有兴趣欢迎继续发文讨论。 03/28 20:56
24F:→ empireisme: 其实我有做到那边,在本文的最後一段 03/29 00:42
25F:→ empireisme: 但是那时候想说还是有一层回圈就没继续做了 03/29 00:42
26F:→ andrew43: 一样的,你可以创造出两个非常多重复列但重复方式不同 03/29 01:22
27F:→ andrew43: 的大矩阵以达成所以的对应情况,於是完全不用回圈了。 03/29 01:22
28F:推 andrew43: 技巧上可用rep产生不同的重复列号索引来生成二个大矩阵 03/29 01:27
29F:→ andrew43: 。 03/29 01:27
30F:→ empireisme: ok 03/30 13:57
31F:→ Gjerry: 也许可以这样写,在我电脑上其实用 for 的function比较快 03/30 14:55
33F:→ andrew43: 抱歉前一大段手边没电脑,现在补上 03/30 16:51
35F:→ empireisme: 大神们感恩! 03/30 20:53