- 개요
관측 자료를 다루다보면 특정 기간에 자료가 아예 없거나 결측이라고 표기된 경우가 많습니다.
특히 결측이 간헐적으로 있을 때 일일이 결측 기간을 확인하기 어렵습니다.
이번 포스트에서는 이런 문제를 해결하고자 결측 기간을 확인하기 위한 시각화를 해보겠습니다.
- 데이터 처리
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()
'대기과학 > 프로그래밍' 카테고리의 다른 글
[기상청 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 |