kma-data-api/verify_wind_vectors.py

61 lines
2.2 KiB
Python

import pandas as pd
import numpy as np
import glob
import os
# 1. 대상 파일 목록 확보 (정의 파일 제외)
files = [f for f in glob.glob('weather_data_*.csv') if 'definition' not in f]
if not files:
print("Error: No weather data files found.")
exit(1)
all_results = []
print(f"--- 총 {len(files)}개 파일 검증 시작 ---")
for file in files:
df = pd.read_csv(file)
# 풍향(wd)을 라디안으로 변환
wd_rad = np.radians(df['wd_10m'])
ws = df['ws_10m']
# 계산된 U, V 성분 (기상학적 공식 적용)
u_calc = -ws * np.sin(wd_rad)
v_calc = -ws * np.cos(wd_rad)
# 실제 데이터와의 차이 (절대 오차)
u_diff = np.abs(u_calc - df['uu'])
v_diff = np.abs(v_calc - df['vv'])
all_results.append({
'file': file,
'u_error_mean': u_diff.mean(),
'v_error_mean': v_diff.mean(),
'u_error_max': u_diff.max(),
'v_error_max': v_diff.max()
})
# 2. 결과 종합
res_df = pd.DataFrame(all_results)
print("\n[검증 통계 요약]")
print(f"평균 오차 (U): {res_df['u_error_mean'].mean():.4f}")
print(f"평균 오차 (V): {res_df['v_error_mean'].mean():.4f}")
print(f"최대 오차 (U): {res_df['u_error_max'].max():.4f}")
print(f"최대 오차 (V): {res_df['v_error_max'].max():.4f}")
# 샘플 데이터 출력 (첫 번째 파일의 상위 5개 행)
sample_df = pd.read_csv(files[0]).head(5)
sample_wd_rad = np.radians(sample_df['wd_10m'])
sample_df['u_calc'] = -sample_df['ws_10m'] * np.sin(sample_wd_rad)
sample_df['v_calc'] = -sample_df['ws_10m'] * np.cos(sample_wd_rad)
print("\n[상세 데이터 샘플 비교 (첫 번째 파일)]")
# 비교를 위해 반올림 처리
print(sample_df[['tm', 'wd_10m', 'ws_10m', 'uu', 'u_calc', 'vv', 'v_calc']].round(4))
if res_df['u_error_mean'].mean() < 0.1:
print("\n결론: 풍향/풍속과 U/V 성분은 수학적으로 동일한 벡터임이 검증되었습니다.")
print("오차(평균 0.05 미만)는 소수점 반올림 및 저장 과정에서 발생하는 미세한 차이입니다.")
else:
print("\n결론: 유의미한 오차가 발견되었습니다. 정의를 재확인할 필요가 있습니다.")