시계열 데이터를 다루다가 데이터가 지속적으로 수집되지 않고 중간 중간 결측이 발생하고 있음이 발견되었다.
결측이 발생하게 되면 모델 학습과 운영에 있어서 크리티컬한 문제기 때문에 결측을 채우는 것이 맞는지, 결측을 어떻게 채워야 하는지, 모든 값에 대해서 채우는 것이 맞는지 고민이 필요하다.
결측에 대해서 단순히 전체 데이터의 결측 개수나 비율을 계산하여 판단할 수도 있겠지만,
시계열 데이터에서는 데이터의 연속성이 중요하기 때문에 데이터의 결측이 연속적으로 얼마나 지속되었는지 살펴 볼 필요가 있다.
그래서 결측에 대해 직관적으로 살펴보기 위해 시계열 그래프를 그려 살펴보고자 했고,
결측이 얼마나 지속되었는지에 따라 결측 보간방법을 다르게 하기 위해 특정 시간 이상 결측이 지속되는 경우는 따로 표시했다.
[ 그래프 시각화 방법 ]
1) 시간에 흐름에 따른 데이터 시각화 => x축을 datetime으로
2) 결측 지속 시간 표시 => datetime 기준으로 오름차순 후, diff()를 이용해 row마다의 시간 차이를 계산
3) 특정 시간 이상 결측 강조 표시 => 새로 데이터가 들어온 시간에 수직선으로 결측지속시간과 함께 표시
시각화 과정에서 결측이 지속된 시간을 바로 알 수 있도록 그래프 위에 text를 표시하게 되었는데
이때 matplotlib 패키지의 text 함수를 이용하면 된다.
주요 파라미터는 아래와 같고, 그 외에 fontsize, color, fontstyle 등 지정하고 싶다면 matplotlib.pyplot.text 설명 페이지를 참고 하면 된다.
plt.text(x, y, s, fontdict=None, **kwargs)
- x: x축 위치
- y : y축 위치
- s : text
- horizontalalignment(ha) : 수평 방향 정렬 {'left', 'center', 'right'}
- verticalalignment (va) : 수직 방향 정렬 {'baseline', 'bottom', 'center', 'center_baseline', 'top'}
import matplotlib.pyplot as plt
## 시간 컬럼 전처리
df = df.sort_values('datetime').reset_index(drop=True)
df['datetime'] = pd.to_datetime(df['datetime']) # 시간 컬럼 datetime 타입으로 변환
df['time_diff'] = df['datetime'].diff() # 시간 차이 계산
## 시각화
plt.figure(figsize=(15, 5))
over_2_idx = df[df['time_diff'] > pd.Timedelta(hours=2)]
plt.title(f"Over 2 hours Graph")
for i in range(len(over_2_idx)):
plt.axvline(over_2_idx['datetime'].iloc[i], color='red', linestyle='--', alpha=0.7)
plt.text(over_2_idx['datetime'].iloc[i], 37, str(over_2_idx['time_diff'].iloc[i]), ha='center', va='top', rotation=30)
df.set_index("datetime")['tmpt_vl'].plot()
text가 겹치지 않도록 rotation으로 각도를 주었는데, 찾아보니 auto-wrapping text 기능도 제공하고 있어
wrap=True 옵션으로 text의 길이도 자동으로 보정이 가능하다. (참고 : Auto-wrapping text 사이트)
import matplotlib.pyplot as plt
fig = plt.figure()
plt.axis((0, 10, 0, 10))
t = ("This is a really long string that I'd rather have wrapped so that it "
"doesn't go outside of the figure, but if it's long enough it will go "
"off the top or bottom!")
plt.text(4, 1, t, ha='left', rotation=15, wrap=True)
plt.text(6, 5, t, ha='left', rotation=15, wrap=True)
plt.text(5, 5, t, ha='right', rotation=-15, wrap=True)
plt.text(5, 10, t, fontsize=18, style='oblique', ha='center',
va='top', wrap=True)
plt.text(3, 4, t, family='serif', style='italic', ha='right', wrap=True)
plt.text(-1, 0, t, ha='left', rotation=-15, wrap=True)
plt.show()
'데이터분석' 카테고리의 다른 글
시계열에서 변화된 지점 찾기 : Change Point Detection (CPD) 기법 (2) | 2024.10.27 |
---|---|
[데이터시각화] 지수표현(+e)된 축 눈금 일반 숫자 형식으로 바꾸기 (0) | 2024.03.20 |
[Python] 조건에 해당하는 array 값 변경 (0) | 2024.02.21 |
[Python] min-max 벗어난 값을 min, max값으로 대체하기 (0) | 2024.02.21 |