QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3329|回复: 0
打印 上一主题 下一主题

《R语言入门与实践》第十章:向量化编程

[复制链接]
字体大小: 正常 放大

1178

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2023-7-31 10:17
  • 签到天数: 198 天

    [LV.7]常住居民III

    自我介绍
    数学中国浅夏
    跳转到指定楼层
    1#
    发表于 2021-11-24 19:54 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
             《R语言入门与实践》第十章:向量化编程  p4 Z# @* m5 q
    前言

    利用 R 的三大法宝:

    • 逻辑判断
    • 取子集
    • 按元素方式执行
      . C# k" K/ \* `2 ]

    来达到编写高效的代码的目的.
    1 l  Y4 p) D2 v* M6 V这样的代码的特点是可以接受整个向量作为输入,并同时处理向量中的元素.
    ! J8 C- P2 ?6 \8 J通过以下几个案例来阐述向量化编程

    预备知识rep() 函数

    格式: rep(c(-1, 1), 5000000)- c7 @3 a& e+ P$ o5 o- Z, F
    功能:接受某个值/向量以及次数,返回该值/向量的重复执行次数长度的更长的向量

    system.time() 函数

    格式: system.time(function(object)). [; M+ }0 ^8 n2 G4 U+ h& U3 _* a
    功能:输入一个语句,返回执行该语句所耗费的时间.

    向量化代码向量化代码的定义

    可以接受一个含有多个值的向量作为输入,并且同时操作向量中的每一个元素

    如何编写向量化代码

    原则:

    • 尽量使用向量化的函数来完成任务:比如使用 R 库中的原函数
    • 对于重复的情况,使用逻辑值取子集的方法,而不是 for & if 的方法.
      5 z3 v) ]  g1 E8 X
    方法一:使用向量化的函数/查找表

    程序①——未经向量化

    change_symbols <- function(vec){
    , @3 P$ N  m% ~$ @: b/ J9 s! wfor(i in 1:length(vec)){: i$ [8 Q) Y$ L# K/ @
    if(vec == "DD"){) U5 D' w' B, g* t% n  M3 @
    vec <- "joker". i* P  s( q! O# B! Y9 O6 O! v' L
    }else if(vec == "C"){
    0 L6 y7 L9 B# Q% x2 x0 Xvec <- "ace"
    + \. W6 \7 A8 |2 e3 d$ ]* m# L}else if(vec == "7"){. L4 b9 ^+ M# m& ~8 a
    vec <- "king"
    9 }* c" V  [9 Z: t+ j}else if(vec == "B"){  p8 l- u7 L- k
    vec <- "queen"
    ( `' I  K, I( a  S# I5 ?" r}else if(vec == "BB"){
    - r" `/ }! ~& E- [vec <- "jack"
    # _$ u2 |% r2 U) f: i! W}else if(vec == "BBB"){
    + |0 h7 t- Q  j3 d$ n* yvec <- "ten"
    5 H8 F% |; l. u}else{1 a& G- ^* N" L5 J
    vec <- "nine"5 ~+ L, f7 r6 L( e" R0 c% Y3 E
    }
    ! k  s2 E* \) D; r3 Y) Y: E5 i% c}
    6 y8 H3 @- s/ N; i" Tvec
    - B' H7 d# {# ?6 h$ V. Q, z}

    程序②——向量化

    change_vec <- function(vec){7 o- F  A6 H- R; t* r" c+ c  r
    prob <- c("DD" = "joker", "C" = "ace"...)
    - Q; _) B2 j+ U: g5 Nunname(prob[vec])
    1 B2 n4 N5 u. G; c" y" \}

    * f  ]) A1 R5 }& {1 @/ ]. r% E  }
    方法二:逻辑值取子集

    目的:一次性完成对一类情况中的所有元素的操作
    * q- }7 Q( ?; s8 L8 p案例:- G% z! n- _% o- T% h, k: {
    程序①——未经向量化

    abs_loop <- function(vec){, O* P$ |* W8 H: d
    for(i in 1:length(vec)){
    2 K2 u0 I/ r2 T( ]if(vec < 0){, w8 y- Z% H* B, a
    vec <- -vec
    . A) @( a  M/ i. y}
    & n% Z& L: v1 F7 D, V$ z}
    ' v4 R* I1 i7 }1 o+ g% vvec
    : D% z6 p' P2 g5 l- M' R}

    程序②——向量化

    abs_set <- function(vec){
    ( h. Q. ^- w+ m% `" b: fnegs <- vec < 00 X/ J5 l% u' ]
    vec[negs] <- vec[negs] * -1
    & o; {& f# Y! pvec
    " N9 x. S  L% I/ O5 q}

    未向量化的程序:$ \& ~: a# H- t8 i; N  p$ }- a
    if 语句一次只能针对一个元素进行判断,来判断出 vec 中为负数的元素
    " J7 z7 v0 F% L6 p; z向量化的程序:; n5 `- ?* Q2 D4 R) S. Z
    其中, vec < 0 为逻辑测试,返回一个包含 TRUE, FALSE 逻辑值的向量 negs, 通过逻辑值取子集的方法,得到 vec 中为负数的元素, 即 vec[negs].

    如何在 R 中编写出快速的 for 循环原则:
    • 能放在循环外的代码,就一定不要放在循环内
    • 确保用来储存循环输出结果的对象必须具备足够的容量,以容纳循环的结果. {; B& m# h4 X
    范例:一个循环 1000000 次并赋值的 for 循环

    在 for 循环之前,定义好一个含有 1000000 个 NA 值的向量.
    - p7 Q7 g1 @+ {4 V) S& c9 T: O在 for 循环之中, 对于对一个向量中的元素进行相应的操作.


    $ t$ e7 G9 A0 t0 \, b  v5 @# C
    ! f  K# ~' S7 x+ B6 |) a# t# @1 ?! [
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-7-18 10:33 , Processed in 0.370518 second(s), 50 queries .

    回顶部