1. 因为向量化,我选择R

3. 向量化问题(Vectorize) - 图1

我们的所有操作,都可以对向量的每一个元素执行。

同样的操作也可以用来取子集:

3. 向量化问题(Vectorize) - 图2

  • 一些使用的注意事项

一般来说,c() 是创建向量的语法,但R 也提供了一些例外:

可不要因为它们养成坏习惯了哦。

3. 向量化问题(Vectorize) - 图3

2. 尽可能的向量化

我觉得下面的内容讲的更全:

https://www.yuque.com/mugpeng/rr/01r-de-bian-cheng-xiao-lu

这里提一下Vectorize函数,可以将标量(接受单一参数的)函数转换为向量化形式:

  1. if_else_statement <- function(vec_element) {
  2. if(vec_element == "Fire") {
  3. vec_element = "hot"
  4. } else {
  5. vec_element = "cold"
  6. }
  7. return(vec_element)
  8. }
  9. vectorized_if_else <- base::Vectorize(if_else_statement)
  10. test001 <- c(rep("Fire", 100000), rep("Ice", 200000))
  11. system.time(sapply(test001, if_else_statement))
  12. system.time(vectorized_if_else(test001))
  13. system.time(ifelse(test001 == "Fire", "hot", "cold"))

这里顺便再比较了另外两种向量化操作的方式:

  1. > system.time(sapply(test001, if_else_statement))
  2. 用户 系统 流逝
  3. 0.471 0.036 0.669
  4. > system.time(vectorized_if_else(test001))
  5. 用户 系统 流逝
  6. 0.434 0.020 0.572
  7. > system.time(ifelse(test001 == "Fire", "hot", "cold"))
  8. 用户 系统 流逝
  9. 0.070 0.005 0.086

这里有人还做了一张图:https://thatdatatho.com/vectorization-r-purrr/#:~:text=base%3A%3AVectorize%20%28%29%20converts%20a%20scalar%20function%20to%20a,vectorize%20functions%20would%20be%20with%20the%20purrr%20package.

3. 向量化问题(Vectorize) - 图4

可见还是尽量不要用Vectorize 做向量化操作呀。

3. 非向量化的情况

  • 输入为上一次输出

但其实有的如cumsum cumprod 等也考虑到了一些基本的运算。

  • 应对策略

尽量避免循环和嵌套次数。

4. 过度向量化问题

  • apply 的本质

我竟然一直喜爱的apply 其实是:

A common reflex is to use a function in the apply family. This is not vectorization, it is loop-hiding. The apply function has a for loop in its definition.

3. 向量化问题(Vectorize) - 图5

  • 内存的消耗

3. 向量化问题(Vectorize) - 图6

所以本质还是空间与时间的tradeoff。

  • 是否需要优化我的代码

当然了。

但如果,花两小时时间将lapply 修改为doLapply 就为了提高脚本0.1s 的速度,我劝你还不如打两把游戏。

5. 记住这句话

3. 向量化问题(Vectorize) - 图7