Преобразование строк в столбцы в perl [duplicate]

Скажите, что у вас есть DataFrame:

>>> df = pd.DataFrame([['hello', 'hello world'], ['abcd', 'defg']], columns=['a','b'])
>>> df
       a            b
0  hello  hello world
1   abcd         defg

Вы всегда можете использовать оператор in в выражении лямбда для создания вашего фильтра.

>>> df.apply(lambda x: x['a'] in x['b'], axis=1)
0     True
1    False
dtype: bool

Трюк здесь состоит в том, чтобы использовать опцию axis=1 в apply для передачи элементов в функцию лямбда по строкам, в отличие от столбца по столбцу.

14
задан jerrygo 15 July 2010 в 02:12
поделиться

8 ответов

Таким образом, это решение использует массив массивов, каждый вложенный массив представляет собой строку данных. Очень просто вы перебираете столбцы в каждой строке и нажимаете их на другой массив массивов, используя индекс столбца, в качестве индекса, который должен вызывать значение. Это влияет на поворот данных по вашему запросу.

#!/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
12
ответ дан dalton 21 August 2018 в 13:05
поделиться
  • 1
    Спасибо. Отличное решение :) – jerrygo 14 July 2010 в 20:51
  • 2
    Вам не нужно нажать для инициализации: @rows = ( [qw(0 1 2 3 4 5 6 7 8 9 10)], [qw(6 7 3 6 9 3 1 5 2 4 6)] ); – dolmen 15 July 2010 в 15:08
  • 3
    Это правда, вам не нужно. Но, как и все остальное в perl, есть несколько способов сделать это. :) – dalton 15 July 2010 в 15:38
  • 4
    $#{$row} написано более кратко (и, на мой взгляд, более читаемо) $#$row – flies 8 November 2012 в 18:48
  • 5
    Не могли бы вы объяснить эту часть? push(@{$transposed[$column]}, $row->[$column]);? В основном, $row->[$column] пожалуйста – Sosi 26 October 2016 в 08:44
use List::UtilsBy qw/zip_by/;

my @transposition = zip_by { [ @_ ] } @matrix;

https://metacpan.org/pod/List::UtilsBy#zip_by

1
ответ дан Arseni 21 August 2018 в 13:05
поделиться
  • 1
    Добро пожаловать в StackOverflow! Не могли бы вы объяснить код в вашем ответе и суммировать соответствующие части ссылки ? – kdbanman 21 October 2015 в 21:37
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, имеет значение

0
ответ дан burnes 21 August 2018 в 13:05
поделиться

Конечно, есть, и Майк указал на самый простой способ. Если вы учитесь, вы, вероятно, захотите написать свою собственную функцию? Во-первых, вы хотите расколоть каждую строку в пробелах, чтобы получить массив значений (или нажмите список слов слов в массив, как в Ответ Далтона , в Perl всегда есть более чем один способ сделать что-либо). Затем, для каждого элемента в массиве , вы хотите напечатать его и его копию во втором массив на одну строку. (Что вы будете делать, если один массив закончится раньше другого?)

Конечно, если вы хотите изучить Perl, вы также определенно захотите научиться использовать CPAN, так что все равно стоит попробуйте использовать Data :: Pivot.

3
ответ дан Community 21 August 2018 в 13:05
поделиться
  • 1
    Спасибо вам за ваши предложения. Я бы определенно их попробовал. – jerrygo 14 July 2010 в 20:49
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";
}
1
ответ дан dolmen 21 August 2018 в 13:05
поделиться

Вот схема одного из способов переноса данных. Работа с этим примером будет поучительной, потому что вам нужно будет использовать 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.
}
5
ответ дан FMc 21 August 2018 в 13:05
поделиться

Вот мой новый скрипт для переноса файла с разделителями табуляции. Измените \ 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'$n=@F-1if!$n;for(0..$n){push@{$$m[$_]},$F[$_]}'\
'END{print map{join"\t",@$_,"\n"}@$m}'
2
ответ дан minopret 21 August 2018 в 13:05
поделиться

как насчет Array-Transpose-0.06?

http://metacpan.org/pod/Array::Transpose

0
ответ дан szabgab 21 August 2018 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: