我已经开始学习perl并喜欢尝试新事物。在perl中转置
我在文本处理中遇到了一些问题。 我有形式的一些文字,
0 1 2 3 4 5 6 7 8 9 10
6 7 3 6 9 3 1 5 2 4 6
我要转此文本。就像,我想将行作为列和列作为行。有没有办法在Perl中做到这一点?
谢谢大家。
我已经开始学习perl并喜欢尝试新事物。在perl中转置
我在文本处理中遇到了一些问题。 我有形式的一些文字,
0 1 2 3 4 5 6 7 8 9 10
6 7 3 6 9 3 1 5 2 4 6
我要转此文本。就像,我想将行作为列和列作为行。有没有办法在Perl中做到这一点?
谢谢大家。
所以这个解决方案使用了一个数组数组,每个嵌套数组 是一行数据。非常简单,您可以循环遍历每行 中的列,并使用索引 索引作为将值推入的索引将它们推送到另一个数组阵列。这可以根据您的要求转换数据的效果 。
#!/usr/bin/env perl
my @rows =();
my @transposed =();
# This is each row in your table
push(@rows, [qw(0 1 2 3 4 5 6 7 8 9 10)]);
push(@rows, [qw(6 7 3 6 9 3 1 5 2 4 6)]);
for my $row (@rows) {
for my $column (0 .. $#{$row}) {
push(@{$transposed[$column]}, $row->[$column]);
}
}
for my $new_row (@transposed) {
for my $new_col (@{$new_row}) {
print $new_col, " ";
}
print "\n";
}
这导致:
0 6
1 7
2 3
3 6
4 9
5 3
6 1
7 5
8 2
9 4
10 6
当然有,而且迈克指出了最简单的方法。如果你正在学习,你可能想写自己的功能?
首先,你要split在空间每行获得值的数组(或push的list of words到阵列,如Dalton's answer;在Perl,总是有做任何事情的方法不止一种)
然后,for each element in the array,你想把它和第二个数组中的对象打印到同一行上。 (你会做什么,如果一个数组用完之前其他?)
当然,如果你想学习Perl的,你也一定要学会使用CPAN一样,所以它仍然是值得用数据来尝试::枢。
谢谢你的建议。我一定会尝试这些。 – jerrygo 2010-07-14 19:49:53
这里的转置数据的一种方法的概述。通过这个例子的工作将是有益的,因为您将需要使用CPAN,您将了解到有用的List::Util
和List::MoreUtils
模块,您将学习复杂数据结构的基础知识(请参阅perlreftut,perldsc和perllol),您将得到在Perl中使用迭代器。
use strict;
use warnings;
use List::MoreUtils qw(each_arrayref);
my @raw_data = (
'0 1 2 3 4 5 6 7 8 9 10',
'6 7 3 6 9 3 1 5 2 4 6',
);
my @rows = ... ; # Look up map() and split() to fill in the rest.
# You want an array of arrays.
my @transposed; # You will build this in the loop below.
my $iter = each_arrayref(@rows); # See List::MoreUtils documentation.
while (my @tuple = $iter->()){
# Do stuff here to build up @transposed, which
# will also be an array of arrays.
}
谢谢。将尝试所有这些:) – jerrygo 2010-07-14 19:49:34
use strict;
# read the first line
my @labels = split ' ', <>;
# read and ignore the empty second line
<>;
# read the third line
my @values = split ' ', <>;
# transpose (I suppose you'll do more with the table than just printing it)
my %table = map { $labels[$_] => $values[$_] } 0..$#labels;
# print
foreach (@labels) {
print "$_ $table{$_}\n";
}
这里是我的新的脚本来转制表符分隔的文件。如果您喜欢,请将\ t更改为您的分隔符。
#!/usr/bin/perl -anF/\t|\n/
$n = @F - 1 if !$n;
for $i (0..$n) {
push @{ $m->[$i] }, $F[$i];
}
END {
for $r (@$m) {
print join("\t", @$r), "\n";
}
}
或作为104字符 “一个衬里”(与撇号反斜杠换行符撇号加入,以避免水平滚动):
perl -anF'\t|\n' -e'[email protected]!$n;for(0..$n){[email protected]{$$m[$_]},$F[$_]}'\
'END{print map{join"\t",@$_,"\n"}@$m}'
如何关于阵列的移调-0.06?
use List::UtilsBy qw/zip_by/;
my @transposition = zip_by { [ @_ ] } @matrix;
Weclome to StackOverflow!你可以请**解释你的答案中的代码**和**总结链接的相关部分**? – kdbanman 2015-10-21 21:37:38
use strict;
my ($i, $rows, $cols) = (0, 10, 100);
# initiate array 10x100
my $array = [map {[map {$i++} (1..$cols)]} (1..$rows)];
# transpose array into 100x10 array
my $transpose = [map {[map {shift @$_} @$array]} @{$array->[0]}];
阵列必须是一个矩阵,即列必须是相等的每一行,原始阵列将被破坏
这个代码将不使用额外的用于转置的内存,用于其他库的x2,用于大型阵列的例如100x1M,重要的是
感谢您的编辑。 :)让我知道如何将重要数据放在该块内。下次我会照顾它:) – jerrygo 2010-07-14 19:04:51
每行缩进4个空格。 – 2010-07-14 19:08:31
我想真正的Perl的方式是使用CPAN模块,如[Data :: Pivot](http://search.cpan.org/~bdulfer/Data-Pivot-0.05/Pivot.pm),但这可能不是你以后的挑战...... – Mike 2010-07-14 19:10:42