첫 번째 행을 기준으로 열을 정렬하는 방법은 무엇입니까?

첫 번째 행을 기준으로 열을 정렬하는 방법은 무엇입니까?

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

  1. 첫 번째 행에 대해 MWell Known을 사용하면 Schwartzian maneuver열이 숫자 정렬 순서(M1, M2, M3, ...)로 표시되도록 재정렬된 인덱스가 제공됩니다.
  2. 남은 것은 이 인덱스를 사용하여 요소를 @I재배열하 는 것입니다.@F
  3. 큰따옴표로 배열을 할당하면 요소가 공백으로 구분된 문자열로 변환됩니다.
  4. -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 "";
}

관련 정보