用结构体,由于有些NA,可能要用两个 hash,不过楼主这点数据跑了3天,这也太那个了吧。 实在不行就用 C 来做吧。
2010/9/8 meng gao <[email protected]>: > 导入数据库,按第一列分组,其他列求avg多方便 > > 在 2010年9月8日 上午11:30,Helc <[email protected]>写道: >> >> #!/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 <[email protected]> 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列,这种情况下,这个程序就不是一 >> > 两天能跑完的了。我跑了三天,还没有跑完。工作情况是不允许我跑这么久的。 >> > >> > 恳请高手们帮忙指教。非常感谢! >> >> -- >> 您收到此邮件是因为您订阅了 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 访问此网上论坛。 > -- 您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。 要向此网上论坛发帖,请发送电子邮件至 [email protected]。 要取消订阅此网上论坛,请发送电子邮件至 [email protected]。 若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。
