首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用"dplyr“是慢的,有更快的方法吗?

用"dplyr“是慢的,有更快的方法吗?
EN

Stack Overflow用户
提问于 2016-10-04 09:00:06
回答 2查看 2.1K关注 0票数 2

我只是试着用我的x,y,z数据框架来计算与参考向量的相对角度。到目前为止,我使用dplyr对事物进行分组,并应用我的angle函数获得相对角度。然而,即使对于我在这里提供的虚拟数据,事情也是非常缓慢的。

代码语言:javascript
复制
set.seed(12345)

x <- replicate(1,c(replicate(1000,rnorm(50,0,0.01))))
y <- replicate(1,c(replicate(1000,rnorm(50,0,0.01))))
z <- replicate(1,c(replicate(1000,rnorm(50,0.9,0.01))))
ref_vector <- data.frame(ref_x=rep(0,100),ref_y=rep(0,100),ref_z=rep(1,100)) 
set <- rep(seq(1,1000),each=50)

data_rep <- data.frame(x,y,z,ref_vector,set)

代码语言:javascript
复制
head(data_rep)
#           x            y         z ref_x ref_y ref_z set
#    1  0.005855288 -0.015472796 0.9059337     0     0     1   1
#    2  0.007094660 -0.013354359 0.9040137     0     0     1   1
#    3 -0.001093033 -0.014661486 0.9047502     0     0     1   1
#    4 -0.004534972 -0.002764655 0.9070553     0     0     1   1
#    5  0.006058875 -0.008339952 0.8926551     0     0     1   1
#    6 -0.018179560 -0.008412400 0.9055541     0     0     1   1

我用这个angle函数定义了两个向量之间的角度,

代码语言:javascript
复制
angle <- function(x,y){
  dot.prod <- x%*%y 
  norm.x <- norm(x,type="2")
  norm.y <- norm(y,type="2")
  theta <- acos(dot.prod / (norm.x * norm.y))
  as.numeric(theta)
}

然后,让我们将其应用于我们的data_rep

代码语言:javascript
复制
library(dplyr)
system.time(df_angle <- data_rep%>%
  rowwise()%>%
  do(data.frame(.,angle_rad=angle(unlist(.[1:3]),unlist(.[4:6]))))%>%
  group_by(set)%>%
  mutate(angle=angle_rad*180/pi, mean_angle=mean(angle)))

#     user  system elapsed 
#      64.22    0.08   64.81 
#    Warning message:
#    Grouping rowwise data frame strips rowwise nature 

正如你所看到的,这个过程大约花了1分钟,我甚至没有提供我所有的真实数据集,它有350000行,它需要10分钟来计算相对角度。

我想知道是否有办法加快这一进程。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-04 09:41:35

只需做一个简单的mutate语句,而不是do(data.frame())部件。这大大提高了性能,因为不再需要将每一行转换为data.frame

代码语言:javascript
复制
system.time(df_angle2 <- data_rep%>%
              rowwise() %>% 
              mutate(angle_rad=angle(x = c(x,y,z),y = c(ref_x,ref_y,ref_z))) %>%
              group_by(set)%>%
              mutate(angle=angle_rad*180/pi, mean_angle=mean(angle)))

##      user      system     elapsed 
##      3.72        0.00        3.71

all.equal(df_angle,df_angle2)
##   TRUE
票数 7
EN

Stack Overflow用户

发布于 2016-10-04 09:59:35

只需为自己发现线性代数:

代码语言:javascript
复制
m1 = as.matrix(data_rep[, 1:3])
m2 = as.matrix(data_rep[, 4:6])

system.time( {
  m1 = m1 / sqrt(rowSums(m1 ^ 2))
  m2 = m2 / sqrt(rowSums(m2 ^ 2))  
  RESULT <- acos(rowSums(m1 * m2))
})
#   user  system elapsed 
#  0.004   0.001   0.006 
all.equal(df_angle$angle_rad, RESULT)
# TRUE
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39848194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档