관측 자료의 결측을 시각화하기

2024. 5. 22. 15:45·대기과학/프로그래밍

- 개요

관측 자료를 다루다보면 특정 기간에 자료가 아예 없거나 결측이라고 표기된 경우가 많습니다.

특히 결측이 간헐적으로 있을 때 일일이 결측 기간을 확인하기 어렵습니다.

이번 포스트에서는 이런 문제를 해결하고자 결측 기간을 확인하기 위한 시각화를 해보겠습니다.

- 데이터 처리

ASOS나 AWS는 결측값이 많이 없기 때문에 결측이 잦은 일단위 강 수위 자료의 결측값을 시각화하겠습니다.

import pandas as pd
import numpy as np
import glob

""" 강 수위 자료(excel) 읽기 (시간간격은 daily) """
inpath = '' # 자료의 경로 입력
files = os.listdir(inpath)
fns = [file for file in files if file.endswith('.xls')]

dfs = []
for fn in fns:
    df = pd.read_excel(inpath+fn)
    df = df.iloc[:-2] # 강 수위 자료의 마지막 두 줄은 관측소에 대한 정보가 있습니다.
    dfs.append(df)
df = pd.concat(dfs)


""" 자료 전처리 """
""" 
강 수위 자료에서 관측이 아예 되지 않은 시간대가 있으므로 
1983년 1월 1일부터 2022년 12월 31일까지 하루 간격으로 모든 날짜 자료를 만듭니다.
"""
syr, fyr = 1983, 2022 # 자료의 시작, 끝 연도
full_date = pd.date_range(start=f'{syr}-01-01', end=f'{fyr}-12-31', freq='D')
df_date = pd.DataFrame()
df_date['date'] = full_date

df['date'] = pd.to_datetime(df['관측일'])

"""
'data' 열을 기준으로 두 데이터프레임을 합칩니다(on='date').
이 때 how='left'의 의미는 df_date의 'date'열 기준으로 합치겠다는 뜻입니다.
특정 날짜에 강 수위 자료가 있다면 그 날짜에 df 행을 추가하고, 없다면 NaN을 추가합니다.
"""
df_merge = pd.merge(df_date, df, on='date', how='left')

 

- 시각화

import matplotlib.pyplot as plt
import seaborn as sns

# YYYY(연도)와 MMDD(월일)을 기준으로 그림을 그려야하므로 해당 열을 추가합니다.
df_merge['YYYY'] = df_merge['date'].dt.year
df_merge['MMDD'] = df_merge['date'].dt.strftime('%m-%d')

"""
pivot을 사용하면 heatmap_data 변수에는 그림을 그릴 때 기준으로 
'YYYY'는 y축, 'MMDD'는 x축, 일 수위는 x,y 좌표의 값이 들어감
"""
pivot_table = df_merge.pivot('YYYY', 'MMDD', '일수위')


heatmap_data = pivot_table.isna().astype(int) # 결측은 1 아니면 0을 반환

"""
heatmap_data의 차원은 (40, 366)입니다.
40은 총 연도고 366은 2월 29일이 포함된 1년의 날 수입니다.
윤년이 아닌 연도는 2월 29일이 없으므로 결측이라고 보기 어렵습니다.
이 부분에는 -1을 넣어주겠습니다.
"""
for year in range(syr, fyr+1):
    if year%4 != 0:
        heatmap_data.loc[year,'02-29'] = -1

plt.figure(figsize=(15, 8))
# gray:-1(2월 29일), green:0 (관측 있음), red:1(결측)
sns.heatmap(heatmap_data, cmap=['gray', 'green', 'red'], cbar=False)

# x축, y축에 검은 선을 수동으로 그려야 함
plt.axhline(y=0, color='black', linewidth=2)
plt.axvline(x=0, color='black', linewidth=2)

plt.xlabel('MM-DD')
plt.ylabel('YYYY')
plt.show()

강 수위 자료의 결측 유무

 

저는 두 가지 색으로 결측 유무만 확인했지만

pivot_table 변수를 대상으로 적당한 colormap을 설정해주면 관측값을 한 눈에 확인할 수 있습니다.

pivot_table = df_merge.pivot('YYYY', 'MMDD', '일수위')
plt.figure(figsize=(15, 8))
sns.heatmap(pivot_table, cmap='jet')
plt.axhline(y=0, color='black', linewidth=2)
plt.axvline(x=0, color='black', linewidth=2)

plt.xlabel('MM-DD')
plt.ylabel('YYYY')
plt.show()

강 수위 관측의 heatmap

 

'대기과학 > 프로그래밍' 카테고리의 다른 글

[기상청 API][ASOS 시간(hourly) 자료 다운로드] 2. 장기간 자료 다운로드 받기  (1) 2024.05.29
[기상청 API][ASOS 시간(hourly) 자료 다운로드] 1. 기본 제공 URL 사용  (0) 2024.05.24
[folium] matplotlib을 활용한 온도 공간 분포 시각화  (0) 2024.05.14
[folium] 지도에 ASOS 관측소 위치 표시하기  (0) 2024.05.10
[python] 지도에 대한민국 행정 단위 경계 그리기  (1) 2024.04.29
'대기과학/프로그래밍' 카테고리의 다른 글
  • [기상청 API][ASOS 시간(hourly) 자료 다운로드] 2. 장기간 자료 다운로드 받기
  • [기상청 API][ASOS 시간(hourly) 자료 다운로드] 1. 기본 제공 URL 사용
  • [folium] matplotlib을 활용한 온도 공간 분포 시각화
  • [folium] 지도에 ASOS 관측소 위치 표시하기
레까
레까
  • 레까
    데이터 조아
    레까
  • 전체
    오늘
    어제
    • 전체 (97) N
      • 일기장 (0)
      • 대기과학 (49) N
        • 프로그래밍 (45) N
        • 개념 (2)
        • 칼럼 (2)
      • 여러가지 데이터 (5)
        • 프로그래밍 & 분석 (5)
      • 프로그래밍 (17)
        • 파이썬 (8)
        • 시각화 (8)
        • 유용 (1)
      • 프로젝트 (21)
        • 기계학습 기반 서울 기온 예측 (9)
        • 사과게임 매크로 만들기 (4)
        • 버스 한 번으로 특정 지역에 갈 수 있는 지역 찾.. (4)
        • 메이플스토리 챌린저스 월드 시즌 1 분석 (4)
      • 데이터리안 SQL 공부 (4)
      • 주제별 링크 모음 (1)
      • 백업 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레까
관측 자료의 결측을 시각화하기
상단으로

티스토리툴바