【问题标题】:perl compute difference of columns in csv fileperl计算csv文件中列的差异
【发布时间】:2011-05-13 23:38:06
【问题描述】:

我有一个 csv 文件(非常大),格式如下。

key1,val1,val2,val3... ,valn
key2,val2,val5,val1....,valn
...
...
keyn,val7,val9,val11....,valn
key1,val2,val4,val8.....,valn
key2,val10,val12,val14..., valn
...
...
keyn,val2,val4,val8.....,valn
key1,val3,val5,val7... ,valn
key2,val0,val9,val3....,valn

key1 到 keyn(及其值)在 csv 文件中重复多次。

值 (val1, valn) 是 double(float)。

我要打印的内容:

1) 从文件的开头开始,对于每个键,我想计算列值(例如 val2、val4、val6)与键的下一次出现之间的差异。

例如

key1,2,4,6
key2,3,5,7
...
...
key1,4,6,8
key2,4,6,8

我要打印

key1:与上一条记录的差异是 key1,2,2,2 key2:与上一条记录的差异是 key2,1,1,1 ..

keyn:与上一条记录的差异是......

2) 对每个键的每次连续出现重复执行此操作。

这就是我的想法(将值存储在哈希中)

#!/usr/bin/perl

my %hash;
open my $fh, '<', 'file1.csv' or die "Cannot open: $!";
while (my $line = <$fh>) {
  $line =~ s/\s*\z//;
  my @array = split /,/, $line;
  my $key = shift @array;
  $hash{$key} = \@array;
}
close $fh;

【问题讨论】:

  • 抱歉... id 不好 -:) 发帖很快... 我确实有有效的电子邮件地址
  • @mystery_man 我猜你的公司很好en.wikipedia.org/wiki/… 更重要的是,你没有很好地解释你的问题。
  • 这感觉很熟悉。作业?
  • 不清楚你在问什么。您是否正在为您的解决方案、更好的解决方案或错误修复寻找 cmets?如果您可以大规模简化问题,那就太好了,例如,只有 2 个数据列。
  • @need_help - 请通过编辑将说明放入问题本身。评论的格式非常糟糕,您上面的评论基本上无法阅读,抱歉。

标签: arrays perl hash diff


【解决方案1】:

我的尝试:

use strict;
use warnings;

use Text::CSV_XS;

use Math::Matrix;



my $csv = Text::CSV_XS->new({binary => 1});

my %hash;

my @results;

open my $fh, '<', 'file1.csv' or die "Cannot open: $!";

while (my $line = <$fh>) {

  if ($csv->parse($line)) {

    my @array = $csv->fields;
    my $key = shift @array;

    if (! exists $hash{$key}) {
      $hash{$key} = \@array;
      next;
    }



    my $previous_record = Math::Matrix->new($hash{$key});
    my $current_record = Math::Matrix->new(\@array);

    my $new_record = $previous_record->add($current_record->negative);

    push @results, @$new_record;

    $hash{$key} = \@array;



  }
  else {
    my $err = $csv->error_input;
    print "error parsing: $err\n";
  }

}

【讨论】:

  • 这也有效。但是,它计算了先前记录和当前记录之间的差异。我想我没有更准确地解释这个问题。非常感谢您的努力。
【解决方案2】:

你可以试试:

    # get the key.
    my $key = shift @array;

    # see if the key is already seen.
    if(exists $hash{$key} ) {
            # get ref to previous record of this key.
            my $ref = $hash{$key};

            # print key.
            print "$key,";

            # a new array.
            my @new_array;

            # populate the new array.
            for(my $i=0;$i<=$#array;$i++) {
                    $new_array[$i] = $array[$i] - $$ref[$i];
            }

            # join the array elements with comma.
            print join",",@new_array;
            print "\n";
    }

    # add/replace the current array as value for the current key.
    $hash{$key} = \@array;

You can see the working code here

【讨论】:

  • 非常感谢,codaddict。除了第一个键之外,这一切都很好。
猜你喜欢
  • 1970-01-01
  • 2013-09-02
  • 2014-10-20
  • 1970-01-01
  • 2011-09-23
  • 2023-03-18
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
相关资源
最近更新 更多