매우 큰 데이터 세트(행 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 "";
}