【问题标题】:rearrange data from one column to a row将数据从一列重新排列到一行
【发布时间】:2014-10-19 06:13:36
【问题描述】:

我有以下数据,我需要将第二列作为标题。任何帮助表示赞赏。

数据:

IBM,Voltality,7,73894756.93897434897
IBM,Market,100,983874.34324
GOOG,Sanity,15,8932748
GOOG,Rate Jump,25,873476378.234234
MBLY,Market,340,23423423432.6783

输出:

PRODUCT|Market|Rate Jump|Sanity|Voltality
IBM|100,983874.34324|||7,73894756.93897434897
GOOG||25,873476378.234234|15,8932748|||
MBLY|340,23423423432.6783|||

代码(不完整/不确定是否热到最后):

#!/usr/bin/perl
use strict;
use Getopt::Long;
use warnings;
use Data::Dumper;

my $valsep = ',';

my ( %type, %keys, %ccy, %cnt, %avg );
while (<>) {
    chomp;
    my ( $product, $reason, $count, $lat ) = split /,/;
    my $key = "$product,$reason";

    if ( not exists( $type{$reason} ) ) {
        $type{$reason} = $reason;
    }
    $ccy{$key} = $product;
    $cnt{$key} = $count;
    $avg{$key} = $lat;

}

close(INPUT);

print Dumper ( \%ccy );
print Dumper ( \%type );

my ( %pair, %details );

foreach my $rows ( sort keys %ccy ) {
    print "the key is : $rows and $ccy{$rows}\n";
    foreach my $res ( sort keys %type ) {
        print "The type is : $res and $type{$res}\n";

    }

}

【问题讨论】:

  • 您可能忘记在第一次试用时提及您的代码来解决此问题
  • 我无法完成。以下是我目前得到的。

标签: perl


【解决方案1】:

您只需要在解析数据结构时跟踪您的列和行数据。

以下演示:

#!/usr/bin/perl
use strict;
use warnings;

my $fh = \*DATA;

my %columns;
my %rows;

while (<$fh>) {
    chomp;
    my ( $company, $col, $vals ) = split ',', $_, 3;

    # Track Columns for later labeling
    $columns{$col}++;

    $rows{$company}{$col} = $vals;
}

my @columns = sort keys %columns;

# Header
print join( '|', 'PRODUCT', @columns ), "\n";

for my $company ( sort keys %rows ) {
    print join( '|', $company, map { $_ // '' } @{ $rows{$company} }{@columns} ), "\n";
}

__DATA__
IBM,Voltality,7,73894756.93897434897
IBM,Market,100,983874.34324
GOOG,Sanity,15,8932748
GOOG,Rate Jump,25,873476378.234234
MBLY,Market,340,23423423432.6783

输出:

PRODUCT|Market|Rate Jump|Sanity|Voltality
GOOG||25,873476378.234234|15,8932748|
IBM|100,983874.34324|||7,73894756.93897434897
MBLY|340,23423423432.6783|||

【讨论】:

  • 我写了一些类似这样的东西,但是我浪费了十几行来让列按正确的顺序排列。我猜他们是按照 first 出现在行中的顺序,向后阅读。我没有注意到简单的 alpha 排序会产生相同的结果!
  • 哈哈!当然,我的 alpha 排序只是简单的懒惰,并且希望输出保持一致。在您指出之前,我没有意识到这是 OP 想要的确切顺序。 =)
【解决方案2】:

以下代码将完成这项工作;我没有使用多个散列,而是将所有数据放在散列中。我已将 cmets 放入脚本中以解释发生了什么,以防您不确定。当然,您可以在脚本中删除它们。

#!/usr/bin/perl
use warnings;
use strict;

my %market;
while (<DATA>) {
    next unless /\w/;
    # remove line endings
    chomp;
    # split line by commas -- only split into three parts
    my @col = split ",", $_, 3;
    # save the data as $market{col0}{col1} = col2
    $market{$col[0]}{$col[1]} = $col[2];
}

# create an output file
my $outfile = 'output.txt';
open( my $fh, ">", $outfile ) or die "Could not open $outfile: $!";

my @headers = ('Market','Rate Jump','Sanity','Volatility');

# print out the header line, joined by |
print { $fh } join('|', 'PRODUCT', @headers) . "\n";

# for each product in the market data
for my $p (sort keys %market) {
    # print the product name    
    print { $fh } join('|', $p, 
    # go through the headers using map (map acts like a "for" loop)
    # if the relevant property exists in the market data, print it;
    # if not, print nothing
                  map { $market{$p}{$_} // '' } @headers) . "\n";
}

# this is the input data. You might be reading yours in from a file
__DATA__
IBM,Voltality,7,73894756.93897434897
IBM,Market,100,983874.34324
GOOG,Sanity,15,8932748
GOOG,Rate Jump,25,873476378.234234
MBLY,Market,340,23423423432.6783

输出:

PRODUCT|Market|Rate Jump|Sanity|Volatility
GOOG||25,873476378.234234|15,8932748|
IBM|100,983874.34324|||7,73894756.93897434897
MBLY|340,23423423432.6783|||

【讨论】:

  • @Borodin cmets 是给 OP 的,他是 Perl 的新手。我在代码中放了很多 cmets,希望 OP 会阅读并尝试理解它,而不是仅仅写一些 OP 会剪切和粘贴而一无所获的东西。
猜你喜欢
  • 2013-10-21
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多