최대값을 무작위로 샘플링하여 출력합니다.

최대값을 무작위로 샘플링하여 출력합니다.

나는 상당히 큰 데이터 세트 ~ 5억 행을 가지고 있습니다. 데이터세트는 아래와 같습니다. 열 1은 부동 소수점 숫자이고, 열 2는 mac id(장치 ID)입니다.

1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2

이 문제는 열 2를 그룹화한 후 약 100,000개의 무작위 샘플을 출력한 다음 해당 특정 그룹의 열 1에서 최대값을 찾는 것이 필요합니다.

중간 출력은 다음과 같습니다(col1별로 그룹화).

1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2497.93,d4:0b:1a:39:19:b2

그 후에는 그룹화된 각 열의 최대값이 필요합니다. 출력은 다음과 같습니다.

3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2

마지막 단계는 정말 무작위 샘플을 얻는 것입니다. 출력은 다음과 같습니다.

3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49

이 작업을 수행하는 방법에 대한 아이디어가 있습니다. 저는 이제 막 Linux를 사용하기 시작했는데 이렇게 어려운 작업을 수행하는 방법을 모르겠습니다. 어떤 도움이라도 대단히 감사하겠습니다.

답변1

노력하다

BEGIN { srand() ;r=0 ; FS="," ; before="" ; }
{ if ( $1 > V[$2]) V[$2]=$1 ;
    if ( before != $2 && before != ""  ) {
          r=rand()*100 ;
       if ( r  > 50 ) printf "%s,%s\n",V[before],before ;
        }
 before=$2 ;
 }  data-file.txt

어디

  • if ( $1 > V[$2]) V[$2]=$1; mac의 최대값을 얻습니다.
  • if ( before != $2 && before != "" ) {새로운 mac 값이 나타날 때
  • r=rand()*100 ; if ( r > 50 ) printf "%s,%s\n",V[before],before ;임의의 값을 계산하여 50%를 초과하면 인쇄합니다. (5%, 95%로 변경 가능)

답변2

5억 행은 많은 양의 데이터이므로 이를 처리하기 위해 보다 확장 가능한 방법을 찾고 싶을 수도 있습니다. 즉, 표준 Linux 유틸리티를 사용하여 이 작업을 수행하는 것이 가능합니다.

데이터가 이름이 지정된 파일에 있다고 가정하면 data.txt 다음을 사용하여 터미널에 인쇄할 수 있습니다 cat.

$ cat data.txt
1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2

sort그런 다음 options 를 사용하여 이 출력을 파이프로 연결할 수 있습니다 -t ',' -k 2. 이러한 옵션은 sort쉼표를 구분 기호로 사용하여 데이터를 분할한 다음 두 번째 열의 값을 기준으로 정렬하도록 지시합니다 .

$ cat data.txt | sort -t ',' -k 2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
2497.93,d4:0b:1a:39:19:b2
3314.55,d4:0b:1a:39:19:b2

sort다음 임무에서는 옵션을 사용해야 합니다 -t ',' -k 1 -r. 이렇게 하면 쉼표를 구분 기호로 사용하고 첫 번째 열의 값을 사용하여 정렬됩니다. -r가장 큰 항목을 먼저 제공하여 적절한 순서로 정렬됩니다 .

$ cat data.txt | sort -t ',' -k 1 -r
3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
3314.55,d4:0b:1a:39:19:b2
2872.32,c0:bd:d1:36:bb:49
2854.11,18:f6:43:64:81:67
2497.93,d4:0b:1a:39:19:b2
1616.93,ac:22:0b:a6:22:c3

sort그런 다음 이번에는 옵션을 사용하여 위 예제의 출력을 다시 파이프로 연결 해야 합니다 -t ',' -k 2 -u. 이전과 마찬가지로 -t ','sort -k 2에서는 두 번째 열을 사용하도록 지시하는 반면, 새 옵션은 -usort에 고유한 항목만 유지하도록 지시합니다.

첫 번째 열의 값을 기준으로 데이터를 정렬했기 때문에 고유한 항목을 찾을 때 가장 높은 항목이 먼저 검색됩니다. 그러면 각 MAC 주소에 대해 가장 높은 단일 값이 제공됩니다.

$ cat data.txt | sort -t ',' -k 1 -r | sort -t ',' -k 2 -u
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2

마지막으로 무작위 샘플을 얻으려면 shuf다음 옵션을 사용할 수 있습니다 -n 2. 여기서 2는 원하는 무작위 샘플 수입니다.

$ shuf data.txt -n 2
3856.91,ac:22:0b:a6:22:c3
3314.55,d4:0b:1a:39:19:b2

답변3

기록용. 이것은 작동하는 것 같습니다. 다른 옵션은 작동하지 않습니다.

sort -t "," -k2,2 -k1,1 -r output.txt| awk -F "," '!a[$2]++'|head -100

관련 정보