一个简单的提高效率的办法:
在读入数据的同时进行处理,不要用反复的循环。
while(<FILE>)
{ my @itmes=split(/\s+/);
  foreach (1..$#items)
  { next if $items[$_] eq 'NA';
    $hash{$items[0]}->[$_]->{sum}+=$items[$_]; #这是总和
    $hash{$items[0]}->[$_]->{count}++; #这是计数
  }
}
这样在读取完输入文件后,进行遍历计数均值同时输出。
不过,这里可能会有一个bug,就是当某个key的某一个列全部是NA的情况下,就会完全不输出而被跳过……

总之,不能反复的做循环。
估计这样运行起来的时间应该也就是几分钟的事情。

  
jester,[email protected] 
2010-09-08  
----- Original Message -----  
From:   chunjiang he  
To:   perlchina  
Sent:  2010-09-08, 00:33:57 
Subject:  [PerlChina] 求教一个算法 




>求教一个算法,上次问过,但是还是没有搞清楚。 
> 
>比如有这样一个矩阵: 
> 
>sex    7.2  3.8  6.8  9.2  5.6 
>sex    5.4  2.3  4.6  8.9  9.0 
>sex    6.7  NA  7.8  9.0  3.1 
>goo    2.4  6.7  NA  9.0  2.1 
>goo    2.1  5.6  7.8  9.7  1.2 
>pkk    2.5  4.3  6.5  4.9  0.2 
>pkk    2.1  3.4  3.2  NA  4.6 
>pkk    3.2  5.6  6.7  9.1  2.2 
>... 
>... 
>... 
> 
> 
>这个矩阵很简单,就是有一些同名的行,现在我要做的是,把这些同名的行的数据按每一列合并起来,按什么合并,按照每一列的平均值来合并 
> 
>就是说,比如行名为sex的行,第一列数据为: 7.2, 5.4, 6.7 那么第一列的平均值就是(7.2+5.4+6.7)/3=6.4, 
>第二列数据为3.8, 2.3, NA, 那么平均值就是  (3.8+2.3)/2=3, 
>以此类推,得到每一列的平均值,作为最后的值,那么行名为sex的行最后就合并为: 
>sex  6.4  3  .... 
> 
>就是要写这样一个程序,原理很简单吧,但是鄙人的水平有限,写的程序效率上不去。 
> 
>我是这样写的, 
> 
>先用一个hash存下所有的行名:sex, goo, pkk..... 
> 
>然后遍历这个hash, foreach (%hash) { } 
> 
>每一次,把相同行名的行取出来放到一个数...@num中 
> 
>这个矩阵有一个值是确定的,那就是列数是确定的,所以对每一个数...@num, 我用for($i=0;$i<列数;$i++) 
>循环,把每一列取出来,放到一个新的数...@haha中 
> 
>然后for($j=0;$j<@haha;$j++)  �...@haha的平均值算出来,作为这一列的最后的值 
> 
>就是这样。。。 
> 
>程序我是写出来了,对于行数和列数都比较少的情况,程序没有什么问题。但是如果我有大量的行和列,比如有40000行,500列,这种情况下,这个程序就不是一两天能跑完的了。我跑了三天,还没有跑完。工作情况是不允许我跑这么久的。
> 
> 
>恳请高手们帮忙指教。非常感谢! 
> 
>--  
>您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。 
>要向此网上论坛发帖,请发送电子邮件至 [email protected]。 
>要取消订阅此网上论坛,请发送电子邮件至 [email protected]。 
>若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。 
> 

-- 
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 [email protected]。
要取消订阅此网上论坛,请发送电子邮件至 [email protected]。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

回复