【问题标题】:Algorithm for calculating most stable, consecutive values from a database从数据库中计算最稳定的连续值的算法
【发布时间】:2015-03-29 02:05:11
【问题描述】:

我有一些问题,需要您的意见。

假设我有一个包含 2000-3000 行的数据库表,每行都有一个值和一些标识符。我需要提取具有最稳定值(最低价差)的约 100 个连续行。如果可以排除它们,则可以使用一些跳线值。 你会怎么做?你会使用什么算法?

我目前正在为在 Oracle 上运行的数据库使用 SAS Enterprise Guide。我真的不太了解通用 SAS 语言,但我不知道我可以为此使用什么其他语言?一些脚本语言?我的编程知识有限,但这项任务似乎很简单,对吗?

我一直在考虑的算法是:

  1. 选择 100 个连续行并计算标准差。将 select 语句增加 1 并再次计算标准偏差。循环穿过整个桌子。 导出标准差最小的行

  2. 与 1 相同,但计算方差而不是标准差(基本相同)。当整个表被循环后,再做一次,但从 avg 中排除具有最高值的 1 行。重复此过程,直到排除 5 个跳线并比较结果。 与方法一相比的优缺点?

问题:

  • 最好和最简单的方法?
  • 首选语言?在 SAS 中可能吗?
  • 您还有其他推荐的方法吗?

提前致谢

/尼克拉斯

【问题讨论】:

  • 通常我会要求提供代码,但如果您不太了解 SAS 语言,这并不是一件简单的事情。我决定回答是因为我认为这个问题是一个很好的问题,其他人可能会从中找到用处。
  • 第 1 部分的术语是移动标准差。对于第 2 部分,为什么异常值只有最大值,最小值呢?
  • Reeza:嗯,我的方法 2 的意思是排除相对于平均值具有最高值(距离)的数字。罗伯特和雷扎:非常感谢!我今天将尝试代码并比较结果。

标签: sql database algorithm sas filtering


【解决方案1】:

以下代码将满足您的要求。它只是使用一些样本数据,并且只计算 10 次观察(而不是 100 次)。我会留给您根据需要进行调整。

创建一些示例数据。可用于所有 sas 安装:

data xx;
  set sashelp.stocks;
  where stock = 'IBM';
  obs = _n_;
run;

创建行号并按降序排序。更容易计算标准差:

proc sort data=xx;
  by descending obs;
run;

使用一个数组来为每一行保留随后的 10 个 obs。使用数组计算每行的标准差(最后 10 行除外。请记住,我们正在向后处理数据。

data calcs;
  set xx;

  array a[10] arr1-arr10;

  retain arr1-arr10 .;

  do tmp=10 to 2 by -1;
    a[tmp] = a[tmp-1];
  end;
  a[1] = close;

  if _n_ ge 10 then do;
    std = std(of arr1-arr10);
  end;

run;

找出哪个 obs(即行)的标准差计算值最低。将其保存到宏变量中。

proc sql noprint;
  select obs into :start_row
  from calcs
  having std = min(std)
  ;
quit;

从涉及计算最低标准差的样本数据中选择 10 个观察值。

proc sql noprint;
  create table final as
  select *
  from xx
  where obs between &start_row and %eval(&start_row+10)
  order by obs
  ;
quit;

【讨论】:

    【解决方案2】:

    Robert 解决方案的补充,但也包括第 2 部分,创建第二个数组,然后循环并删除前 5 个值。您仍将使用 Roberts 解决方案的最后部分来提取具有最小标准偏差的行,然后是相应的附加行。您没有指定如何处理已删除最大值的方差,因此它们保留在数据集中。

    data want;
    *set arrays for looping;
    /*used to calculate the std*/
    array p{0:9} _temporary_;
    /*used to copy the array over to reduce variables*/
    array ps(1:10) _temporary_; 
    /*used to store the var with 5 max values removed*/
    array s{1:5} var1-var5;
    
    set sample; 
    
    
    p{mod(_n_,10)} = open;
    
    
    if _n_ ge 10 then std = std(of p{*});
    
    *remove max values to calculate variance;
    if _n_ ge 10 then do;
    *copy array over to remove values;
        do i=1 to 10;
            ps(i)=p(i-1);
        end;
    
        do i=1 to 5;
            index=whichn(max(of ps(*)), of ps(*));
            ps(index)=.;
            s(i)=var(of ps(*));
        end;
    end;
    run;
    

    【讨论】:

      猜你喜欢
      • 2016-07-31
      • 2021-02-14
      • 2020-05-28
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      相关资源
      最近更新 更多