使用此处设置的数据:
https://www.dropbox.com/s/gyimxbz5f3v0uq3/kfg.RData?dl=0
执行以下代码:
<script type='text/javascript'>
var markers = [];
var marker;
console.log('About to setup map');
//setup the map
function initialize() {
var mapProp = {
draggable: true,
scrollwheel: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("resultmap-canvas"), mapProp);
// show markers
var myLatLng = {lat: -37.8757303, lng: 145.1277893};
var marker6610 = new google.maps.Marker({
position: myLatLng,
map: map
});
marker6610.setValues( {profileid: 6610, directoryid: 2} );
markers.push(marker6610);
var myLatLng = {lat: -38.0034790, lng: 145.1198805};
var marker5316 = new google.maps.Marker({
position: myLatLng,
map: map
});
marker5316.setValues( {profileid: 5316, directoryid: 2} );
markers.push(marker5316);
//set map bounds
var bounds = new google.maps.LatLngBounds();
for(i=0;i<markers.length;i++) {
bounds.extend(markers[i].getPosition());
}
map.fitBounds(bounds);
}
//execute the map creation
initialize();
// trigger map resize event when map tab is displayed
$("#mapTab").on('shown.bs.tab', function() {
google.maps.event.trigger(map, 'resize');
});
</script>
可行,但真实的设置超过800k行,需要很长时间。在matrix(nrow=1600,ncol=8) -> ctw
for(k in 1:8){
for(i in 1:1600){
which(kfg[,9]==i) -> aj
if(length(aj)!=0){
sample(kfg[aj,11],prob=kfg[aj,k],size=1) -> ctw[i,k]
}
ctw[i,k]
}
}
或其他包中有没有办法更快地完成此操作?执行data.table
步骤非常缓慢。
答案 0 :(得分:4)
我必须修改原始代码以检查非零概率。我还从内循环的最后一行删除了语句ctw[i,k]
,因为它没有效果。你的代码是
matrix(nrow=1600,ncol=8) -> ctw
for(k in 1:8){
for(i in 1:1600){
which(kfg[,9]==i) -> aj
if ((length(aj)!=0) && any(kfg[aj, k] > 0)) {
sample(kfg[aj,11],prob=kfg[aj,k],size=1) -> ctw[i,k]
}
}
}
ctw
我颠倒了循环的顺序,因此kfg[,9] == i
只被评估一次而不是8次。我还使用length(aj) != 0
对循环外的tabulate()
进行了测试。我修改后的代码是
matrix(nrow=1600,ncol=8) -> ctw
which(tabulate(kfg[, 9], 1600) != 0) -> ii
for(i in ii) {
kfg[,9] == i -> aj
for(k in 1:8)
if (any(kfg[aj, k] > 0))
sample(kfg[aj,11], 1, prob=kfg[aj,k]) -> ctw[i,k]
}
ctw
对于您的样本数据,这大约快5倍。
提取样本值kfg[,11] == kfg[[11]]
的向量一次,并使用概率的矩阵as.matrix(kfg[, 1:8])
,而不是data.frame,要快得多。对于样本数据,将第9列上的分割提升到循环之外要快得多,并且通过在循环外进行矢量化计算以确定相关索引来避免k循环内的条件
nrow <- 1600
matrix(nrow=nrow,ncol=8) -> ctw
x <- kfg[[11]]
pr <- as.matrix(kfg[,1:8])
ajs <- split(seq_len(nrow(kfg)), factor(kfg[[9]], levels=seq_len(nrow)))
ii <- seq_along(ajs)[lengths(ajs) > 0]
for(i in ii) {
aj <- ajs[[i]]
kk <- which(colSums(pr[aj,, drop=FALSE]) > 0)
for(k in kk)
sample(x[aj], 1, prob=pr[aj,k]) -> ctw[i,k]
}
ctw
这导致5倍的加速,比原来快25倍。
为了测量速度,我将上述每一项都包含在一个函数中,例如
f0 <- function() {
matrix(nrow=1600,ncol=8) -> ctw
for(k in 1:8){
for(i in 1:1600){
which(kfg[,9]==i) -> aj
if ((length(aj)!=0) && any(kfg[aj, k] > 0)) {
sample(kfg[aj,11],prob=kfg[aj,k],size=1) -> ctw[i,k]
}
}
}
ctw
}
并使用了microbenchmark软件包
> library(microbenchmark)
> microbenchmark(f0(), f1(), f2(), times=10)
Unit: milliseconds
expr min lq mean median uq max neval cld
f0() 466.12527 483.43954 484.34258 483.74805 484.21627 521.19957 10 c
f1() 92.77415 94.79052 94.99273 95.10352 95.45368 96.10641 10 b
f2() 17.33708 17.83257 17.87095 17.87205 18.01723 18.16400 10 a
f1()
和f2()
应该相同,但它们不是
> set.seed(123); res1 <- f1(); set.seed(123); res2 <- f2()
> all.equal(res1, res2)
[1] "'is.NA' value mismatch: 12096 in current 12133 in target"
调查,这是因为第9列中的值是数字,但是被视为kfg[, 9] == i
,就好像它们是整数一样。例如,
> kfg[[9]][(kfg[[9]] > 28 & kfg[[9]] <= 29)]
[1] 29 29 29
> kfg[[9]][(kfg[[9]] > 28 & kfg[[9]] <= 29)] == 29
[1] FALSE FALSE FALSE
也许意图是
kfg[[9]] = round(kfg[[9]])
有了这个改变,我们有
> all.equal(res1, res2)
[1] TRUE
> identical(res1, res2)
[1] TRUE