2010年9月25日星期六

Re: [PerlChina] Re: 求教一个算法

Hi,

呵呵, 不能反复遍历原数据去读取一个key, 应该全部读到hash 中, 遍历hash计算. 如果你的行数多的内存放不下, 就在外面先sort, 然后 就不用hash了, 逐行处理就okay了.  如果是sort 后的 给个简单的架子:

#!/usr/bin/evn perl

use strict;
use warnings;

my $last_key;

while (<>) {
    chomp; 
    
    next if !$_;
    
    my ($key, @vals) =  split / /, $_;
    
    if (!$last_key) {
    } else if ($key eq $last_key) {
    } else {
    } 
}   

if ($last_key) {
    # print the last one
}   

xunxin

2010/9/9 camelbbs <camelbbs@gmail.com>
Thanks so much everyone!

On Sep 7, 10:30 pm, Helc <crys...@gmail.com> wrote:
> #!/usr/bin/perl
> use strict;
> use warnings;
> use Data::Dumper;
>
> my %hash;
> my %line;
> while(<>){
>     my @a = split;
>     for (my $i=0;$i<=($#a-1);$i++) {
>         $hash{$a[0]}->[$i] += ($a[($i+1)] ne 'NA') ? $a[($i+1)] : 0;
>         $line{$a[0],($i+1)}++ if ($a[($i+1)] ne 'NA');
>     }
>
> }
>
> for my $k (keys %hash) {
>     for (my $i=0;$i<=(@{$hash{$k}}-2);$i++) {
>         $hash{$k}->[$i] /= $line{$k,($i+1)};
>     }}
>
> print Dumper(\%hash);
>
> 43000行,35列,试了下,4.04妙
>
> On 9月8日, 上午12时33分, chunjiang he <camel...@gmail.com> wrote:
>
>
>
> > 求教一个算法,上次问过,但是还是没有搞清楚。
>
> > 比如有这样一个矩阵:
>
> > 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列,这种情况下,这个程序就不是一 两天能跑完的了。我跑了三天,还没有跑完。工作情况是不允许我跑这么久的。
>
> > 恳请高手们帮忙指教。非常感谢!- Hide quoted text -
>
> - Show quoted text -

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


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

没有评论: