非常に大きなデータセット(1000行と700000列)の列を並べ替える必要があります。たとえば、col1 col4 col3 col2など、ランダムに配置された列があり、それらをソートする必要があります。
私は成功せずにいくつかのコマンドを試しました。
例:
ID M2 M5 M8 M1 M3 M9 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln
この例では、ポイントは列と線が多いことを意味します。同様に、次のように列を並べ替える必要があります。
ID M1 M2 M3 M4 M5 M6 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln
ありがとう
答え1
GNUと共にdatamash
そしてGNU sort
:
datamash transpose -t ' ' -H <file_in.csv | sort -V | datamash transpose -t ' ' -H >file_out.csv
これは「かなり小さい」データに適しています。あなたのファイルにうまくいくかもしれませんし、うまくいかないかもしれません。
編集する:前置きのない次のソリューションは、あまりにも多くのリソースを占有してはいけません。
答え2
perl -pale '
$. == 1 and
@I = map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [ $F[$_] =~ /^M(\d+)$/, $_ ] } 1..$#F;
$_ = "@F[0, @I]";
' yourlargefile
- 最初の行に対して
M
Well Knownを使用すると、Schwartzian maneuver
列が数値ソート順(M1、M2、M3、...)で表示されるように並べ替えられたインデックスが提供されます。 - 残りは、このインデックスを使用して要素を
@I
並べ替えることです。@F
- 二重引用符で配列を割り当てると、要素はスペースで区切られた文字列に変換されます。
-p
$_
コンテンツの自動印刷を可能にするPerlのオプションを追加する-l
必要がありますnewline
。
答え3
Perl モジュールの使用 Sort::Naturally
入力データ
ID M2 M5 M8 M1 M3 M9 M700000
A1 m1,2 m1,5 m1,8 m1,1 m1,3 m1,9 m1,7000000
A2 m2,2 m2,5 m2,8 m2,1 m2,3 m2,9 m2,7000000
A3 m3,2 m3,5 m3,8 m3,1 m3,3 m3,9 m3,7000000
A1000 m1000,2 m1000,5 m1000,8 m1000,1 m1000,3 m1000,9 m1000,7000000
perl -MSort::Naturally -lane '
if ($. == 1) {
@indices = (0, map { $_->[0] }
sort { ncmp($a->[1], $b->[1]) }
map { [$_, $F[$_]] }
1..$#F
);
$, = " ";
}
print @F[@indices]
' test.data
出力
ID M1 M2 M3 M5 M8 M9 M700000
A1 m1,1 m1,2 m1,3 m1,5 m1,8 m1,9 m1,7000000
A2 m2,1 m2,2 m2,3 m2,5 m2,8 m2,9 m2,7000000
A3 m3,1 m3,2 m3,3 m3,5 m3,8 m3,9 m3,7000000
A1000 m1000,1 m1000,2 m1000,3 m1000,5 m1000,8 m1000,9 m1000,7000000
答え4
GNUがある場合は、awk
次のことを試すことができます:
NR == 1 {
for (i = 2; i <= NF; i++) {
columns[substr($i, 2)] = i;
}
count = asorti(columns, sorted, "@ind_num_asc");
printf("%s", $1);
for (i = 1; i <= count; i++) {
printf(" M%s", sorted[i]);
indx[i] = columns[sorted[i]];
}
print "";
next;
}
{
printf("%s", $1);
for (i = 1; i <= count; i++) {
printf(" %s", $(indx[i]));
}
print "";
}