Statistics 板


LINE

※ 引述《cawaiilulu (across)》之铭言: (恕删) : 没关系 这个都不用管 假设就 都两位以下数字 我主要是想问怎麽写比较"快" 我尝试写了一段应用双重 set 回圈的 code 如下(及本文末,防连结失效) https://gist.github.com/anonymous/6f5b3f7f650a990bcfac 先讲测试结果.... 测试条件:SAS 9.4 / win7 x64 / 2.9G 双核心 / ramdisk 20G(SAS工作位置) 以资料笔数 n=1k, m=500k 测试,耗时 real time 144s CPU time 133s 因此合理估计 n=100k, m=500k 时,将花去约13300s, 即3.7小时左右 不晓得这个效率,是否符合您的期待? 然後是最佳化的想法.... 首先您要求的任务,基本上时间复杂度一定是 >= O(nm) 的, 这是因为您不但需要判定「较大变数个数之最大值 (绝大多数情况会是 5)」, 还必须给出最大值的「发生次数」, 所以每一笔 n 跟每一笔 m 都非得做过一次比较,才能取得发生次数之故。 因此,能够最佳化的部份,主要就是下面这些点了: 1.尝试减少 I/O 次数(磁碟读写总是最慢的) 2.减少各种不必要的中间变数。 3.尝试一边读取、一边计算、一边更新,仅用 n*m 次资料存取就解决问题。 (i.e.就资料 I/O 的部份,把常数压到 1) 另外,这个 case 我认为 set 双回圈的作法一定远远优於 proc sql。 因为这两个表格的合并方式是不带条件的 Cartesian join, 并且用 proc sql 来处理的话,还需要制造 5 个 dummy variable, (case when then else end 的写法,大概非这样不可,至少我写不出其他作法) 所以一定会产生一个非常庞大的 (n*m) 中间资料集, 产生大量不必要的I/O。 相较之下,data step 的 set 双回圈,在条件判断与资料输出方面,就灵活许多。 对 dataset b 的资料,可以轻易做到读完即丢(见code), 除了结果之外,完全不需创造中间资料集, 因此空间复杂度会永远被压缩在 1*1,而不是 n*m 当然如果我有想错,也请诸位前辈不吝赐教~ m(_ _)m 附:测试程式码 %let NA = 1000; * expect 100k; %let NB = 500000; * expect 500k; /* generate test dataset */ data a; ID = 0; do while (ID < &NA); ID + 1; V1 = ranuni(777); V2 = ranuni(777); V3 = ranuni(777); V4 = ranuni(777); V5 = ranuni(777); output; end; run; data b; ID = 0; * ID of b is of no use; do while (ID < &NB); ID + 1; V1 = ranuni(911); V2 = ranuni(911); V3 = ranuni(911); V4 = ranuni(911); V5 = ranuni(911); output; end; run; /* match */ data result(keep=ID CNT); set a; N = 0; * the current maximum value of "# of bigs"; CNT = 0; * the # of occurence of current N; i = 0; * pointer for random accessing dataset b; do while (i < NN); i+1; /* read i-th obs of dataset b */ set b(rename=(V1-V5=BV1-BV5) drop=ID) point=i nobs=NN; /* find "# of bigs" of this i-th obs */ N_this = 0; if V1 - BV1 > 0 then N_this = N_this + 1; if V2 - BV2 > 0 then N_this = N_this + 1; if V3 - BV3 > 0 then N_this = N_this + 1; if V4 - BV4 > 0 then N_this = N_this + 1; if V5 - BV5 > 0 then N_this = N_this + 1; /* take action based on the value of N_this */ * case 1: N_this < N -> discard all data of b (do nothing); if N_this < N then do; end; * case 2: N_this = N -> update CNT; else if N_this = N then CNT = CNT + 1; * case 3: N_this > N -> replace N by N_this and reset CNT value; else do; N = N_this; CNT = 1; end; /* output to see how N and CNT change gradually (should limit the value of &NA and &NB!) */ *output; end; run; --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.39.232.118
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Statistics/M.1434760473.A.B0A.html ※ 编辑: realtemper (114.39.232.118), 06/20/2015 08:42:07
1F:→ MOONY135: 我的感觉会很慢 06/20 11:17
2F:→ realtemper: 请赐教 06/20 17:28
3F:→ MOONY135: 喔 我是说我上一篇的CODE 我用SQL写的 06/20 22:02
4F:→ realtemper: 嗯 试过了,你的其实不是慢,是不能解决问题 -- 因为 06/21 01:15
5F:→ realtemper: 中间资料集太大了(100*500k即达2.6G) 06/21 01:16
6F:→ realtemper: 100k*500k就会需要吃掉>2T。 06/21 01:18







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP