楼主: Kaeder
5893 5

[问答] data步骤的where语句问题 [推广有奖]

  • 0关注
  • 0粉丝

VIP1+

高中生

45%

还不是VIP/贵宾

-

威望
0
论坛币
8735 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
1841 点
帖子
14
精华
0
在线时间
28 小时
注册时间
2016-5-19
最后登录
2020-1-19

20论坛币
我有一个很大的dataset叫做rawdata,里面有symbol,date和其他列。我知道如果想从里面提取出特定symbol的数据,可以用下面的语句:

data mydata;
  set rawdata;
  where symbol = 'AAA';
run;

但是我想提取的symbol有很多,那应该怎么用where语句做呢?我想提取的symbol储存在一个叫symlist的dataset里,里面只有symbol这一列。

我试过sql语句,但是因为rawdata很大,读取起来很花时间。如果能够用where语句的话会快很多。

我可能要介绍一下rawdata这个dataset的详细情况:
rawdata来自在另一个硬盘上,按照date排列的文件集。每150日时长的文件读取需要一个小时(如果不用where语句限制的话),而我要读十几年的数据。事实上,我是用set语句里的open=defer这个选项把原来的文件读取出来并合并成一个新的dataset,叫做rawdata。
所以如果不直接在where里限制symbol,而是用sql、merge或者其他proc对rawdata进行预处理都会要很久。

关键词:data步 Where HERE Data whe where语句 SAS
沙发
BraveMadMan 发表于 2017-4-3 13:25:14 |只看作者 |坛友微信交流群
proc sort data=rawdata; by symbol;
proc sort data=symlist; by symbol;
DATA mydata;
        MERGE rawdata symlist (in=a);
        BY symbol;
        if a;
RUN;
已有 1 人评分经验 论坛币 学术水平 热心指数 收起 理由
admin_kefu + 10 + 10 + 2 + 2 热心帮助其他会员

总评分: 经验 + 10  论坛币 + 10  学术水平 + 2  热心指数 + 2   查看全部评分

使用道具

藤椅
Kaeder 发表于 2017-4-3 14:41:34 |只看作者 |坛友微信交流群
BraveMadMan 发表于 2017-4-3 13:25
proc sort data=rawdata; by symbol;
proc sort data=symlist; by symbol;
DATA mydata;
谢谢你的回答,不过我可能要说一下rawdata这个dataset的详细情况。
rawdata来自在另一个硬盘上,按照date排列的文件集。每150日时长的文件读取需要一个小时(如果不用where语句限制的话),而我要读十几年的数据。事实上,我是用set语句里的open=defer这个选项把原来的文件读取出来并合并成一个新的dataset,叫做rawdata。
所以如果不直接在where里限制symbol,而是用sql、merge或者其他proc对rawdata进行预处理都会要很久。

使用道具

板凳
dogmamongo 发表于 2017-4-3 22:09:12 |只看作者 |坛友微信交流群
proc sql;
   create table mydata as select *
   from rawdata
   where symbol in (select symbol from symlist);
quit;

这会不会快一点  
已有 1 人评分论坛币 热心指数 收起 理由
admin_kefu + 10 + 2 热心帮助其他会员

总评分: 论坛币 + 10  热心指数 + 2   查看全部评分

使用道具

报纸
sonypam 在职认证  发表于 2017-4-4 10:22:03 |只看作者 |坛友微信交流群
Hash Object可能会有帮助,代码如下,当你的symlist越大的时候,这种方法的运行速度比使用SQL越有优势。比如使用Hash的办法,下面的代码在我的机器上运行时间Real Time:42.17 seconds,CPU Time:19.26 seconds,使用上贴中SQL办法,运行时间Real Time:53.14 seconds, CPU Time: 28.24 seconds.
其实无论怎么设计方法,最后还是要把整个rawdata一行一行执行一遍,这部分才是最消耗时间的,我们公司也经常处理非常大的data,通常的办法是把大data拷贝到固态硬盘(SSD)上,在SSD上读写速度比普通硬盘都会快很多。比如说我们之前一个大data,在普通硬盘上光读的就需要40多分钟,后来改到在SSD硬盘上,读数据的时间只需要1分半钟,大大提高工作效率。希望我的解答对你有帮助。

/* Create a Fake Symbol Data*/
data symlist;
        do symbol = 1 to 1000;
                output;
        end;
run;
  
%let seed = 20170403;

/*Create a Fake Large Data*/
data rawdata;
        mindate = "01JAN2002"d;
        maxdate = "01JAN2017"d;
        range = maxdate - mindate + 1;
        do i = 1 to 1e8;
                symbol = ceil(5000 * ranuni(&seed));
                date = mindate + ceil(ranuni(&seed)*range);
                format date date9.;
                output;
        end;
        keep symbol date;
run;

data select;
        if _N_ = 1 then do;
                declare hash h(dataset:"symlist");
                h.definekey('symbol');
                h.definedone();
        end;
        set rawdata;
        if h.find() = 0 then do;
                output;
        end;
run;
已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 20 + 20 + 2 + 2 + 2 热心帮助其他会员

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

使用道具

地板
soporaeternus 发表于 2017-4-5 16:10:46 |只看作者 |坛友微信交流群
symbol 不太多可以用宏
一般多用hash
非常多的话就别用sas了

楼上说转到SSD的话,除非数据要许多次读写,否则一次全量IO的开销未必合算。

使用道具

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

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

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

GMT+8, 2024-4-26 15:34