반응형

    정보

    • 업무명     : Awk를 이용하여 텍스트/숫자 빅데이터 자료 처리 및 통계 계산

    • 작성자     : 이상호

    • 작성일     : 2020-07-15

    • 설   명      :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 기상 연구 및 웹 개발을 담당하고 있는 해솔입니다.

    • 텍스트 형식의 숫자 데이터 처리 및 분석은 Awk + 쉘 스크립트가 유용합니다.

    • 특히 기상 자료와 같은 빅데이터엑셀이나 C 언어, Fortran 등으로 자료 처리한 경우 더욱 더 필요합니다.

    • 오늘 포스팅은 Awk를 이용하여 텍스트/숫자 빅데이터 자료 처리 및 통계 계산을 소개드리고자 합니다.

     

     

    [특징]

    • 빅데이터 자료 처리를 이해하기 위해서 Awk이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 소프트웨어

     

    [기능]

    • 빅데이터 자료 처리

    • 통계 계산

     

    [활용 자료]

    • 파일명 : sample.txt

    • 자료 종류 : 날짜 및 시간에 따른 광합성 유효 복사 (Photosynthetic Active Radiation, PAR)

    • 시간 해상도 : 5분 간격

    • 열 정보 : 연도, 쥴리안 데이 (Julian Day), 시분, 센서 1, 센서 2, 센서 3

    • 쥴리안 데이의 경우 1월 1일에서 12월 31일을 365으로 설정

    • 시분은 1 또는 2 자리에서 의미 (예를 들어 605은 오전 6시 05분)

    • 센서 1의 경우 상단 및 센서 2, 3은 하향에서의 측정값을 의미하고 각각 센서의 전압 (mV)로 표현

    • 실질적인 물리적인 값 (mol/m2/sec)으로 변환하기 위해서 변환 계수를 고려

    • 각 열마다 쉼표로 구분

     

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 작업 환경 구축

    • 소스 코드 작성 및 실행

    • 실행 결과 확인

     

    [사용 OS]

    • Linux (CentOS v7.0)

    • VMware Workstation Pro v15.5

     

    [사용 언어]

    • Shell Script (Bash)

     

     빅데이터 자료 처리

    [명세]

    • 작업 환경

      • sample.txt : 입력 자료

      • RunShell.sh : 실행 프로그램

     

    • 센서 1-3에서 각 변환 계수 (293.73, 306.82, 290.84)를 통해 물리적 변수 환산

      • BEGIN { FS = "," }를 통해 각 행의 열을 , (쉼표)로 구분하여 전압 출력 (mV x 변환 계수)

      • 일반적으로 FS는 공백 또는 탭으로 기본값 지정   

    #!/bin/bash
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } { 
          print $1, $2, $3, $4*293.73, $5*306.82, $6*290.84 
       }'

     

     

    • 연속적인 시간 스케일을 위해 시분을 하루의 분으로 표시

      • 즉 시분의 경우 불연속 구간 존재하기 때문에

      • 예를 들어 6:59분 이후로 6:60가 아니라 7:00으로 불연속 발생

    #!/bin/bash
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } { 
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2, min + hour*60, $4*293.73, $5*306.82, $6*290.84
       }'

     

     

    • 하루에 대한 시계열을 위해 1일 단위로 스케일 조정

    #!/bin/bash
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } {
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
       }'

     

     

    • 표준 출력 (>)을 통해 conv.txt 저장 

    #!/bin/bash
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } {
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
       }' > conv.txt

     

     

    • gnuplot를 통해 센서에 따라 시간별 물리값 시각화

    #!/bin/bash
    
    gnuplot << EOF
       set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
       set output "Image_01.png"
       set title "PAR"
       set yrange [0:2500]
       set ylabel "PAR [umol/m2/sec]"
       set xlabel "DAY (2005)"
       plot "conv.txt" u 2:3 title "above canopy" w l, "conv.txt" u 2:4 title "under canopy" w l, "conv.txt" u 2:5 title "under canopy" w l
    EOF
     
    mogrify -rotate 90 -matte -background none Image_01.png
    display Image_01.png

     

     

    • 이와 같은 쉘 스크립트를 사용하면 다수 장점

      • 1차 데이터에서 최종 결과 (그래프)까지의 처리 과정을 완벽하게 기록할 수 있고 필요 시 손쉽게 재현 가능

      • 동일한 형식의 자료에 대해 반복 수행

      • 자료 처리의 일부를 변경하고 다시 시작하는 것도 쉬움

        • 예를 들어 센서의 출력을 실제 값으로 변환 계수를 변경할 경우

      • 자료 처리의 노하우를 공개하거나 다른 연구자들과 공유하는 것이 용이

     

     통계 계산

    [명세]

    • 센서 1의 출력에 대해 일별 합계 (단위: mol/day) 수행

    #!/bin/bash
    
    cat conv.txt |\
       awk 'BEGIN { D = 170; a = 0; t = 170.0 } 
          D + 1 <= $2 {
             print D, a; a = 0; D++
             } 
          { 
             a = a + $3 * ($2 - t) * 60 * 60 * 24 / 1000000; 
             t = $2
          }'

     

     

    • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

    #!/bin/bash
    
    cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

     

     

    • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

      • 센서 1에서 0일 경우 오류 발생

    #!/bin/bash
    
    cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

     

     

    • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

      • 센서 1에서 0일 경우 오류 발생

    #!/bin/bash
    
    cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

     

     

    • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

      • 계산하기 앞서 조건문 (센서 1 > 0) 수행 

    #!/bin/bash
    
    cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }'

     

     

    • 표준 출력 (>)을 통해 trans.txt 저장

    #!/bin/bash
    
    cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }' > trans.txt

     

     

    • 센서 2/3에 대한 시간별 투과율 시각화

    #!/bin/bash
    
    gnuplot << EOF
       set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
       set output "Image_02.png"
       set title "PAR Transmittance"
       set yrange [0:1]
       set ylabel "PAR Transmittance"
       set xlabel "DAY (2005)"
       plot "trans.txt" u 2:3 title "sensor 2" w l, "trans.txt" u 2:4 title "sensor 3" w l
    EOF
    
    mogrify -rotate 90 -matte -background none Image_02.png
    display Image_02.png

     

     

    [전체]

    #!/bin/bash
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } { 
          print $1, $2, $3, $4*293.73, $5*306.82, $6*290.84 
       }'
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } { 
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2, min + hour*60, $4*293.73, $5*306.82, $6*290.84
       }'
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } {
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
       }'
    
    cat sample.txt |\
       awk 'BEGIN { FS = "," } {
          min = $3 % 100; 
          hour = ($3 - min) / 100; 
          print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
       }' > conv.txt
    
    gnuplot << EOF
       set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
       set output "Image_01.png"
       set title "PAR"
       set yrange [0:2500]
       set ylabel "PAR [umol/m2/sec]"
       set xlabel "DAY (2005)"
       plot "conv.txt" u 2:3 title "above canopy" w l, "conv.txt" u 2:4 title "under canopy" w l, "conv.txt" u 2:5 title "under canopy" w l
    EOF
     
    mogrify -rotate 90 -matte -background none Image_01.png
    display Image_01.png
    
    cat conv.txt |\
       awk 'BEGIN { D = 170; a = 0; t = 170.0 } 
          D + 1 <= $2 {
             print D, a; a = 0; D++
             } 
          { 
             a = a + $3 * ($2 - t) * 60 * 60 * 24 / 1000000; 
             t = $2
          }'
    
    cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'
    
    cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }'
    
    cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }' > trans.txt
    
    gnuplot << EOF
       set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
       set output "Image_02.png"
       set title "PAR Transmittance"
       set yrange [0:1]
       set ylabel "PAR Transmittance"
       set xlabel "DAY (2005)"
       plot "trans.txt" u 2:3 title "sensor 2" w l, "trans.txt" u 2:4 title "sensor 3" w l
    EOF
    
    mogrify -rotate 90 -matte -background none Image_02.png
    display Image_02.png

     

     참고 문헌

    [논문]

    • 없음

    [보고서]

    • 없음

    [URL]

    • 없음

     

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com

     

     

     

     

     

     

     

     

     

     

    본 블로그는 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기