QQ登录

只需要一步,快速开始

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

sas提高处理大数据效率的一些实用技巧

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

937

主题

117

听众

3万

积分

升级  0%

  • TA的每日心情

    2020-10-25 11:55
  • 签到天数: 264 天

    [LV.8]以坛为家I

    自我介绍
    内蒙古大学计算机学院

    社区QQ达人 金点子奖 助人为乐奖 风雨历程奖

    群组2013年数学建模国赛备

    跳转到指定楼层
    1#
    发表于 2014-4-17 15:38 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    摘要: 测试代码的时候,可以从大数据集中抽取一部分数据来进行测试,而不比直接在大文件上全部进行测试。抽取数据这个有好多种方法常用的如使用obs=option选项,proc surveyselect进行分层抽样,利用种子产生随机数来抽取等 ...- P$ t- r" O$ L

    0 o5 _8 s1 ?! s  D. ?3 Y) y' N
    5 T4 B. d- F2 b0 B, b
    4 |0 c. x5 U+ `% C- I
    以下是自己总结的一些方法,欢迎拍砖,添砖加瓦。. O. M! o- A, d
    1.测试代码的时候,可以从大数据集中抽取一部分数据来进行测试,而不比直接在大文件上全部进行测试。抽取数据这个有好多种方法常用的如使用obs=option选项,proc surveyselect进行分层抽样,利用种子产生随机数来抽取等等,反正怎么方便怎么取。如
    proc means data=test(obs=1000);
    run;
    或者
    options obs=1000;   
    proc means data=test;   
    run;
    options obs=max;
    2.每个数据集最好只保留自己想要的变量,变量太多是会影响效率的,所以无关变量可以drop掉,或者keep想要的变量。
    3 ^8 T, j0 Y- w5 @
    3.在对符合已知变量条件的记录进行处理时,果断先进行筛选,然后在进行处理。同时在 Data步建立新数据集,在进行的条件筛选中,where的效率比if高,因为where在读入的时候就已经进行判断,而if则是等到全部读完的时候才进 行判断。如需对class数据集中的男生建立一个新变量weight_new,以下这种写法是不可取的。
    6 a0 U% c% k5 K$ ?5 a
    data test;
                set sashelp.class;
                weight_new=sum(height,-101);
                if  sex=”男”;
         run;
    可以这么写
    data test;
                set sashelp.class(Where =(sex=”男”));
                weight_new=sum(height,-101);
         run;
    4.一些能省略的data步,如先经过data步进行简单的条件筛选,然后进行proc步的一些操作,诸如此类的data步,尽量省略吧。
    data test;
                    set  sashelp.class;
                    where  sex=”男”;
         run;
         proc means data=test;
                    var  weight height;
         run;
    完全可以这么写
    proc means data=test(where=(sex=”男”));
                    var  weight  height;
         run;
    5.需要修改数据集变量的label和format格式时,还是通过proc datasets过程进行修改效率比较快,它不需要记录进入pdv,比起data步更有效率。
    data test;           
         set sashelp.class;           
          label weight="体重(斤)";            
          format weight best6.2;   
    run;      
    , ^& M& l+ d) b+ \- k" u7 z
    proc datasets library=sashelp;            
         modify class;            
         label weight="体重(斤)";           
         format weight best6.2;   
    run;   
    quit;
    6.纵向合并数据集时,如果生成的目标表就是来源表之一,那么proc append会比data步更有效率。
    data test1;
           do  i=1 to 10000000;
                  x=1;y=1;z=1;
           output;
           end;
    run;
    * J" q) y3 L* K, A' D1 Q
    data test2;
           do  i=1 to 10000000;
                x=1;y=1;z=1;
                output;
        end;
    run;
       data test1;
              set test1 test2;
        run;

    9 u. S1 K  H; v4 M. F9 ^
    /*proc append*/
        data test1;
              set test1;
              stop;
        run;
        proc append base=test1 data=test2;
        run;
    /*proc datasets中的append*/
        data test1;
              set test1;
              stop;
        run;
    proc datasets library=work;
    modify test;
    append base=test1data=test2;
    run;
    quit;
    proc append和proc datasets中的append过程效率是一样的。
      a: k: ]  G" r9 f
    7.对于大数据集,一般都会讲数据集压缩,以节省存储空间,sas里可以通过options compress=yes;来进行压缩。
    . P5 h$ L, D+ t7 d$ }
    8.如果我们想要查看一个变量顶部5%的记录,可以通过proc rank一步实现,而不需先通过univariate过程先将p95分位数求出,然后赋值给宏变量,最后再回到数据集中筛选。
    data test;
            do   i=1 to 200;
                output;
            end;
        run;
        proc rank data=test groups=100 out=want(where=(i_pct>=95));
              var    i;
              ranks   i_pct;
        run;
    9.在编写一些proc步时,对于分组变量最好是用class而不用by,因为用by是得对分组变量进行排序的。
    2 Q0 D, m. s: e6 g& C1 h
    10.视图的应用。视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是, 视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。所以视图能够节省大量的空间,同时 因为它不是以存储的形式存在,因此在一定程序上能够提高运行效率。如对生成的数据集进行means过程
    data test1/view=test1;
            do i=1 to 30000000;
                  x=1;y=1;z=1;output;      
            end;   
    run;     
    proc means data=test1;         
            var   i;   
    run;

    0 H8 F; c5 \$ N- p: Z
    data test2;
           do i=1 to 30000000;
                x=1;y=1;z=1;
           output;
           end;   
    run;     
    proc means data=test2;        
           var   i;   
    run;
    对比之下,我们可以看到视图比起数据集将近节省了10秒。但是引用视图的时候要注意,视图的名字能够覆盖视图的名字,但是它不能覆盖数据集的名字,因此建 立视图的时候,不能存在跟视图一样名字的数据集,否则会报错。同时,如果视图的名字存在,再要建立同样名字的数据集也是会报错。

    / G4 B7 E7 J1 O5 n4 ~

    - q( i1 O3 C! v, g2 Y11.format格式数据集的引用。比如说在信用卡交易数据集,每天的交易量都是很大的,同时包括境内境外交易,这时就存在币种转换问题。一张交易量很 大的表,和一张币种汇率表,这时如果通过币种去连接两个数据集,首先得先对这两个数据集按币种排序,然后merge进行计算,当然有人想到直接用sql连 接,不过这样消耗时间也都是非常大的。这时候就可以先将汇率表做成format的数据集形式,到时就可以直接使用了。如
    data rate;
    input currency $ rate date yymmdd10.;
    format date yymmdd10.;
    cards;
    USD 6.13 2013/6/11
    EUR 8.14 2013/6/11
    GBP 9.56 2013/6/11
    JPY 5.80 2013/6/11
    HKD 0.78 2013/6/11
    ;
    run;

    0 \. y+ q9 |# ~: _0 N+ F+ Y
    data trans;
    input id $ currency $ money;
    cards;
    001 USD 200
    002 GBP 100
    003 USD 120
    004 HKD 1000
    005 EUR 300
    ;
    run;

    ' O( P9 V  }8 O# R4 A
    proc sort data=rate nodupkey;
            by currency;
    run;
    : V' y: Z. y7 S- Y1 e
    data rate_format;
            set rate end=last;
            retain fmtname 'rate_fmt' type 'c';
            rename currency=start rate=label;
            drop date;
    run;

    4 C( I! {6 m  l8 s( I/ l
    /*options fmtsearch=(sashelp);*/

    % h5 ?) c+ L. T# {/ H
    proc format library=work cntlin=rate_format;
    run;

    : }- l8 W/ I0 t5 x1 t2 k
    data trans_amt;
            set trans;
            rate=put(currency,$rate_fmt.);
            money_to_rmb=money*rate;
    run;
    注意format数据集的地址,如果非work逻辑库下,则需要加上这么一句话options fmtsearch=(逻辑库名称);

    # ]$ h7 T7 Z- f; D8 Y
    12.将数据集载入内存。该方法减少数据集内存分配和释放的次数,降低I/O处理量,提高SAS程序执行效率,但是相当消耗内存,需要确认系统有足够多的内存资源,同时在使用完后,要记得释放。具体形式如下
    sasfile test2 load;/*将数据集test2载入内存*/
    data test;
    set test2;
    run;
    proc means data=test2;
    run;
    sasfile test2 close;/*将test2数据集从内存中释放*/
    13.hash的应用。在data步中使用hash对象,不但可以快速有效地检索和读取数据,还可以实现数据集 merge的功能,从而减少排序时间,提高了数据处理的能力,相对于merge,hash的效率更高,但是同时也很消耗内存,因此一般都是把小表放进 hash中。如用前面汇率进行币种的连接
    data test;
            if _n_=0 then set rate;
            if _n_=1 then do;
                    declare hash  share(dataset:'work.rate');
                            share.definekey('currency');
                            share.definedata(all:'yes');
                            share.definedone();
            call missing (of _all_);
            end;
            set Trans;
            if share.find()=0;
    run;
    9 C  k2 `9 {. f6 }! y

    ! l2 h; N4 I7 O/ x1 G9 B9 ~9 i, X6 d. W
    zan
    转播转播 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    张泽华        

    0

    主题

    8

    听众

    1067

    积分

    升级  6.7%

  • TA的每日心情
    奋斗
    2015-6-24 14:21
  • 签到天数: 353 天

    [LV.8]以坛为家I

    自我介绍
    喜欢玩数模
    回复

    使用道具 举报

    谭宝     中国数模人才认证   

    0

    主题

    6

    听众

    339

    积分

  • TA的每日心情
    擦汗
    2018-5-30 18:05
  • 签到天数: 115 天

    [LV.6]常住居民II

    社区QQ达人

    群组2014国赛优秀论文解析

    群组2014年地区赛数学建模

    群组中国矿业大学数学建模协会

    群组华南理工大学

    群组西南大学建模组

    回复

    使用道具 举报

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

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2024-5-17 07:54 , Processed in 0.752107 second(s), 62 queries .

    回顶部