SAS:大文件/多任务:将文件拆分为更小的文件,或将任务拆分

  • 本文关键字:文件 拆分 任务 多任务 SAS sas
  • 更新时间 :
  • 英文 :


我有高频财务数据(毫秒),有很多列,137mio观测值/行,总大小32Gb。我想使用PROC TIMESERIES将观测值聚合到30秒的仓中。我最初的命令涉及很多变量/任务。

proc timeseries data=DATA out= DATA_SEC30; 
id DATETIME interval=sec30 setmissing=missing align=beg start = '01jan1999.00:05'dt end = '01dec2014.00:00'dt; 
var TRADE BID ASK MID / accumulate=last;
var TIME / accumulate=last;
var OF VOL / accumulate=total;
var DATE / accumulate=N;
run;

如果我运行此代码,我会收到以下错误消息:

错误:无法分配足够的内存。至少请求了312070K字节。您必须增加可用内存量,或者以不同的方式处理问题。

我的问题是,解决问题的最佳方法是什么?

A) 根据日期等将文件拆分成更小(不重叠)的文件,然后在每个子文件上运行上面的代码,并在最后将它们放在一起?或

B) 按步骤拆分以上代码,例如每个VAR语句一个,但在完整文件上运行?

答案可能是程序特定的,也可能是计算机特定的(但我希望得到一个"一般"的答案)。我使用PROC TIMESERIES,计算机是一台服务器,SAS被分配了大约256Gb的内存。

首先,鉴于您的特殊问题,我鼓励您联系SAS技术支持。你为SAS支付了很多钱,你得到的一件事是在类似问题上几乎实时的支持——通常来自proc的开发人员自己。一旦你超越了基本的数据步骤和简单的过程,如SUMMARY/MEANS、TABULATE、FREQ等,进入了高内存强度的东西,如TIMESERIES,通常会有一些特定于过程的优化,只有少数人可能知道。

至于在general中,什么方法最适合解决此类问题,没有一个答案。当它不会影响结果时,最好将观察结果分开,而不是为不同的变量重新运行过程。这是因为I/O限制;四次读取相同的32GB与四次读取8GB相比,后者显然更好。当然,有时(比如在回归分析中)这会改变结果,因此是不可取的。

如果可能的话,您也可以使用BY语句来提供帮助。这避免了实际拆分数据集的必要性;相反,您有一些定义组的变量,并运行该ID的BY,允许您在一次过程中通过一次调用运行proc,但可以有效地多次运行分析,并且只生成一个最终输出数据集。这通常(但并不总是)可以避免内存不足的情况。我不知道PROC TIMESERIES是否能处理这个问题,但我认为在你的情况下可能会。

下面是一个示例,使用PROC TIMESERIES文档中的第二个示例。首先,我在整个SASHELP.AIR数据集上运行它,然后是BY yeargroup(四舍五入到5的最近倍数的年份)。请注意SERIES数据集是如何相同的;因此,这部分分析工作很好。但是SEASON数据集并不相同,因为BY组分析意味着每个BY值都有单独的Seasons集。您需要了解PROC TIMESERIES是如何处理您的数据的,以了解BY组是否会影响事情。

 proc timeseries data=sashelp.air
                   out=series
                   outtrend=trend
                   outseason=season print=seasons;
      id date interval=qtr accumulate=avg;
      var air;
   run;

data air;
  set sashelp.air;
  yeargroup = round(year(date),5);
run;
 proc timeseries data=work.air
                   out=series2
                   outtrend=trend
                   outseason=season print=seasons;
      by yeargroup;
      id date interval=qtr accumulate=avg;
      var air;
   run;
   proc compare base=series compare=series2;
   run;

为了在编写最少的代码和资源效率之间取得合理的折衷,我可能会使用不同的数据集选项多次运行proc时间序列,例如

proc timeseries data=DATA(firstobs = 1 obs = 10000000)...
proc timeseries data=DATA(firstobs = 10000001 obs = 20000000)...

在您的情况下,看起来只需将处理分为两次就足够了。像这样使用obsfirstobs可以避免创建索引或临时数据集,也可以避免读取整个数据集两次,因为SAS只需要在第二次运行中寻找firstobs的位置,即不需要实际读取任何先前的观测值。

根据您使用proc timeseries所做工作的复杂性,以及是否有其他人需要在您的服务器上使用大量内存,您可能会发现编写等效的数据步骤是值得的。这将为您提供一次通过的单个输出数据集,并且将消耗更少的内存(可能只有几百KB),但可能需要更多的编写和维护工作。

最新更新