FAQ > 金融建模 > 效率优化 > 数据处理效率优化

Q:将多个表格进行合并计算(哈希表加速)    

  • A:在对数据的处理中,通常需要对多个数据表,进行表连接后,对每行进行运算,一般方式如join处理,可参考:FAQ:Q:如何实现多表连接

    本文中,不展示join处理的方式,对于大数据结果集而言,join方式存在效率问题。
    因此,这里介绍通过建立哈希表,进行快速运算的过程展示,描述常用的两种方式:
    第一种:哈希表合并后对行进行计算(结果整合到一个表中)
    第二种:产生目标哈希集合后,直接计算(更快)


    生成哈希表的两个常用模型:
    指定列为下标,修改后表中不再有该列:FAQ:NormalTabletoStrSubscript
    指定列为下标,修改后该例依然存在:FAQ:ReIndexCopy

    示例展示
    第一种:先对多个目标数组进行合并处理,而后再进行相关的计算。此种方式结果中会记录参考计算的列与结果列
    如:
    //--构造示例数据
        setsysparam(pn_stock(),"SH000001");
        setsysparam(pn_date(),20240822.16T);
        setsysparam(pn_cycle(),cy_1m());
        t1:=Nday(240,'time',datetimetostr(sp_time()),'c',close());
        t2:=Nday(240,'time',datetimetostr(sp_time()),'h',high());
        t3:=Nday(240,'time',datetimetostr(sp_time()),'l',low());
        t4:=Nday(240,'time',datetimetostr(sp_time()),'o',open());
    //--数据处理成哈希表
     //若不需要保存time列,可将reindexcopy改用NormalTabletoStrSubscript
        t1:=reindexcopy(t1,t1[:,"time"]);
        t2:=reindexcopy(t2,t2[:,"time"]);
        t3:=reindexcopy(t3,t3[:,"time"]);
        t4:=reindexcopy(t4,t4[:,"time"]);
    //数组合并,后通过select计算每行的指标
        t:= t1|t2|t3|t4;
        t:= select *,
        100*((['c']+['o'])-(['h']+['l']))/(['h']+['l']) as 'r' from t end;
        t:= Reindex2(t,1); //将字符串行标修改为自然下标
        return t;

    结果展示(部分结果):


    第二种:通过对目标哈希表的下标集合进行循环,计算每个目标的结果。此种方式结果中只记录结果列
    //--构造示例数据
        setsysparam(pn_stock(),"SH000001");
        setsysparam(pn_date(),20240822.16T);
        setsysparam(pn_cycle(),cy_1m());
        t1:=Nday(240,'time',datetimetostr(sp_time()),'c',close());
        t2:=Nday(240,'time',datetimetostr(sp_time()),'h',high());
        t3:=Nday(240,'time',datetimetostr(sp_time()),'l',low());
        t4:=Nday(240,'time',datetimetostr(sp_time()),'o',open());

    //--数据处理成哈希表
     //若不需要保存time列,可将reindexcopy改用NormalTabletoStrSubscript
        t1:=reindexcopy(t1,t1[:,"time"]);
        t2:=reindexcopy(t2,t2[:,"time"]);
        t3:=reindexcopy(t3,t3[:,"time"]);
        t4:=reindexcopy(t4,t4[:,"time"]);
    //直接计算
        mbC:=mrows(t1,1); //目标下标集合---可根据用户需求产生--一维数组
        r:=array();
        for i,m in mbC do
          r[m]["r"]:=100*((t1[m]['c']+t4[m]['o'])-(t2[m]['h']+t3[m]['l']))/(t2[m]['h']+t3[m]['l']);
        //若希望结果是一个二维且保留key值列,则可改用r[m]:=array("time":m,"r":xx计算表达式xx);
        return r;

    结果展示(部分结果):


    注:以上两种方式效率都非常高,且第二种比第一种还要快,用户可根据需求选择。