楼主: 万人往LVR
4315 8

[问答] 如何DIY向量化计算去替代循环? [推广有奖]

  • 1关注
  • 13粉丝

副教授

82%

还不是VIP/贵宾

-

威望
0
论坛币
5127 个
通用积分
816.1888
学术水平
70 点
热心指数
112 点
信用等级
40 点
经验
9088 点
帖子
625
精华
0
在线时间
1182 小时
注册时间
2013-7-18
最后登录
2023-12-6

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
既然for循环、apply速度都远不如向量化计算,那么如何去自定义向量化计算,而不是仅仅限制在R中已有的函数?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:DIY 向量化 apply for循环 appl 如何

回帖推荐

cheetahfly 发表于6楼  查看完整内容

对于第一个问题,确实如此,用C++写的优化后的循环(不考虑C和C++的细微差别),应该只快不慢于最极致的向量化之后的效果。对此,你可以参考一个帖子:《【R】提升R代码运算效率的11个实用方法》(https://bbs.pinggu.org/thread-4405601-1-1.html),仔细看原版的英文贴。 对于第二个问题,恕我不同意该观点,我目前看到的资料,得出的结论是向量化之所以效率高,是因为应用了R语言的底层函数,减少“解释语言”的效率浪费。至 ...

cheetahfly 发表于4楼  查看完整内容

在这个特定的例子中,还算比较好解决的, rowSums(as.matrix(data)^2) 不过,我猜测你想表达是当某些循环非常难以被向量化时,有什么普遍的原则或特别的技巧能够突破瓶颈,尽最大可能地向量化。 我的观点是,向量化的本质是让程序尽可能地靠近“底层”执行,就是C语言代码。当遇到某些瓶颈,就如大神“Hadley Wickham”在《advanced R》中所提到的“Loops that can’t be easily vectorised because subsequent iteration ...
沙发
cheetahfly 在职认证  发表于 2016-2-25 22:22:38 |只看作者 |坛友微信交流群
感觉是一个很大的方向性问题,能结合实例吗?

使用道具

藤椅
万人往LVR 在职认证  发表于 2016-2-25 22:49:59 |只看作者 |坛友微信交流群
cheetahfly 发表于 2016-2-25 22:22
感觉是一个很大的方向性问题,能结合实例吗?
谢谢,就是一个比较宽泛的问题。
举一个例子:
data <- data.frame(V1=1:10,V2=2:11)
如果想要对每行求和,向量化的函数就是rowSums(data),循环就是apply(data,1,sum)

那么如果想对每一行进行更复杂的操作,例如求平方和,循环来做就是
f <- function(x) sum(x^2); apply(data,1,f)
向量化计算如何来做?

使用道具

板凳
cheetahfly 在职认证  发表于 2016-2-25 23:36:12 |只看作者 |坛友微信交流群
万人往LVR 发表于 2016-2-25 22:49
谢谢,就是一个比较宽泛的问题。
举一个例子:
data
在这个特定的例子中,还算比较好解决的,
rowSums(as.matrix(data)^2)

不过,我猜测你想表达是当某些循环非常难以被向量化时,有什么普遍的原则或特别的技巧能够突破瓶颈,尽最大可能地向量化。

我的观点是,向量化的本质是让程序尽可能地靠近“底层”执行,就是C语言代码。当遇到某些瓶颈,就如大神“Hadley Wickham”在《advanced R》中所提到的“Loops that can’t be easily vectorised because subsequent iterations depend on previous ones”。当这个时候,应该果断转向Rcpp包所开创的新天地:C++编程——至少针对核心循环的简单编程并不难。

有了“向量化”和“Rcpp包”后,我感觉基本上R语言在计算效率上就已经不存在编程语言上的瓶颈,只存在编程经验上的瓶颈了。
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
万人往LVR + 5 + 3 + 3 + 3 精彩帖子

总评分: 论坛币 + 5  学术水平 + 3  热心指数 + 3  信用等级 + 3   查看全部评分

使用道具

报纸
万人往LVR 在职认证  发表于 2016-2-26 12:41:21 |只看作者 |坛友微信交流群
cheetahfly 发表于 2016-2-25 23:36
在这个特定的例子中,还算比较好解决的,
rowSums(as.matrix(data)^2)
感谢,感觉打开了新世界大门,不过不太了解C++的循环机制,所以还有几个疑问:
1. 调用C++后仅仅写一个for循环就会达到R中向量化计算的速度了吗?
2. 有人说向量化计算速度快是因为并行化计算,那么调用C++写循环会自动并行化运算吗?
3. 有人说apply系列函数也是向量化的函数,但是又有人测试说apply循环速度与for循环速度差不多,因为循环占用的时间大部分来源于copy数据框。您如何理解?

谢谢!

使用道具

地板
cheetahfly 在职认证  发表于 2016-2-26 14:02:01 |只看作者 |坛友微信交流群
万人往LVR 发表于 2016-2-26 12:41
感谢,感觉打开了新世界大门,不过不太了解C++的循环机制,所以还有几个疑问:
1. 调用C++后仅仅写一个f ...
对于第一个问题,确实如此,用C++写的优化后的循环(不考虑C和C++的细微差别),应该只快不慢于最极致的向量化之后的效果。对此,你可以参考一个帖子:《【R】提升R代码运算效率的11个实用方法》(https://bbs.pinggu.org/thread-4405601-1-1.html),仔细看原版的英文贴。

对于第二个问题,恕我不同意该观点,我目前看到的资料,得出的结论是向量化之所以效率高,是因为应用了R语言的底层函数,减少“解释语言”的效率浪费。至于并行化,那是另外一个方向,另外一个天地了,我们现在零星接触的单CPU多核多线程并行化实在最基础最简单的一种,复杂的诸如利用GPU并行,利用局域网、互联网并行,超级计算机并行等,里面博大精深得很。在R语言层面上,其实你会发现向量化和并行化有时不一定能同时优化,但在C++上就没有这样的矛盾了。C++我了解的很浅,应该不是天然并行化运算的,也要在编程时刻意去设计。

对于第三个问题,我一直觉得apply是隐性的循环,适合从其他语言转过来的人过渡使用,可以增加编程的效率和代码的可读性,但并不是最优的,不光apply(),包括mapply(),sweep()等。如果对R熟练到一定程度,apply族肯定不是优化的终点,同样的函数包括ifelse()等。
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
万人往LVR + 5 + 3 + 3 + 3 精彩帖子

总评分: 论坛币 + 5  学术水平 + 3  热心指数 + 3  信用等级 + 3   查看全部评分

使用道具

7
万人往LVR 在职认证  发表于 2016-2-26 14:44:17 |只看作者 |坛友微信交流群
cheetahfly 发表于 2016-2-26 14:02
对于第一个问题,确实如此,用C++写的优化后的循环(不考虑C和C++的细微差别),应该只快不慢于最极致的向 ...
感谢!

使用道具

8
cheetahfly 在职认证  发表于 2016-2-27 23:02:04 |只看作者 |坛友微信交流群
万人往LVR 发表于 2016-2-26 14:44
感谢!
你客气了。建议你看一篇文章,《Vectorization in R: Why?》By Noam Ross ,@ http://www.r-bloggers.com/vectorization-in-r-why/   文章中对为什么需要向量化?向量对效率的提升体现在哪里?以及apply为什么也被称为“向量化”?等做了很详细的回答。

使用道具

9
soccy 发表于 2016-2-28 10:37:51 |只看作者 |坛友微信交流群
受教了

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-16 03:12