全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
6292 5
2017-04-03
悬赏 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进行预处理都会要很久。
二维码

扫码加我 拉你入群

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

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

全部回复
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;
二维码

扫码加我 拉你入群

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

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

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进行预处理都会要很久。
二维码

扫码加我 拉你入群

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

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

2017-4-3 22:09:12
proc sql;
   create table mydata as select *
   from rawdata
   where symbol in (select symbol from symlist);
quit;

这会不会快一点  
二维码

扫码加我 拉你入群

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

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

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;
二维码

扫码加我 拉你入群

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

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

2017-4-5 16:10:46
symbol 不太多可以用宏
一般多用hash
非常多的话就别用sas了

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

扫码加我 拉你入群

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

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

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群