CSV 파일에서 가역 쌍 일치

CSV 파일에서 가역 쌍 일치

다음과 같은 .csv 파일이 있습니다.

A,B,1999
C,D,1990
B,A,1989
D,A,1990
A,B,1999
...

대략적으로 다음과 같이 다시 정리하고 싶습니다.

A,B,1989,0,B,A,1
A,B,1999,2,B,A,0
C,D,1990,1,D,C,0
D,A,1990,1,A,D,0

즉, 세 번째 열에 기록된 각 값에 대해 해당 쌍의 발생 횟수와 A,B동일한 값의 발생 횟수를 가져오고 싶습니다.B,A

나는 주로 해당 라인을 A,B해당 라인과 일치시키려고 노력하고 있습니다 B,A.

이에 대한 도움을 주시면 대단히 감사하겠습니다.

답변1

암소 비슷한 일종의 영양awk해결책:

awk -F',' '{ k=$1 FS $2 }{ a[k][$3]++; rev[k]=$2 FS $1 }
           END{ 
               for(i in a) 
                   for(j in a[i]) { 
                       print i, j, a[i][j], rev[i], a[rev[i]][j]+0; 
                       delete a[rev[i]][j] 
                   }
           }' OFS=',' file

산출:

C,D,1990,1,D,C,0
A,B,1999,2,B,A,0
D,A,1990,1,A,D,0
B,A,1989,1,A,B,0

답변2

이것은 Perl에서 작동하는 것 같습니다.

perl -F, -alne '
    next if /^\s*$/;
    $hs{$F[2]}{"$F[0],$F[1]"}++;
    END{
        while (my ($nr, $lhs) = each %hs) {
            while (my ($lts, $cnt) = each %{$lhs}) {
                my $rvs = scalar reverse $lts;
                my $rvsn = $hs{$nr}{$rvs} // 0;
                print "$lts,$nr,$cnt,$rvs,$rvsn";
                delete $hs{$nr}{$rvs};
            }
        }
    }
' data

한 줄씩 설명:

  1. 펄 실행, 에프또는 필드를 읽을 구분 기호레이, 조심해마일마다 달리는 엔딩N전자와이자형구현하다:

    perl -F, -alne '
    
  2. 입력 시 빈 줄을 건너뜁니다.

    next if /^\s*$/;
    
  3. 각 레코드의 해시 카운터를 증가시킵니다.

    $hs{$F[2]}{"$F[0],$F[1]"}++;
    
  4. 마지막 블록을 시작합니다:

    END{
    
  5. 해시 값을 읽습니다.

    while (my ($nr, $lhs) = each %hs) {
        while (my ($lts, $cnt) = each %{$lhs}) {
    
  6. 인쇄할 데이터 준비:

    my $rvs = scalar reverse $lts;
    my $rvsn = $hs{$nr}{$rvs} // 0;
    print "$lts,$nr,$cnt,$rvs,$rvsn";
    
  7. 해시에서 쌍 항목을 제거합니다.

    delete $hs{$nr}{$rvs};
    
  8. data입력 파일입니다.

따라서 이 입력 데이터의 경우:

A,B,1999
C,D,1990
B,A,1989
D,A,1990
A,B,1999
B,A,1999

다음과 같은 결과가 출력되어야 합니다.

D,A,1990,1,A,D,0
C,D,1990,1,D,C,0
B,A,1989,1,A,B,0
A,B,1999,2,B,A,1

관련 정보