60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
import pandas as pd
|
|
import numpy as np
|
|
import glob
|
|
|
|
# 1. 대상 파일 목록
|
|
files = [f for f in glob.glob('weather_data_*.csv') if 'definition' not in f]
|
|
|
|
all_rel_errors = []
|
|
|
|
for file in files:
|
|
df = pd.read_csv(file)
|
|
|
|
# 0인 풍속 제외 (상대 오차 계산 불능)
|
|
df = df[df['ws_10m'] > 0.1].copy()
|
|
|
|
wd_rad = np.radians(df['wd_10m'])
|
|
ws = df['ws_10m']
|
|
|
|
u_calc = -ws * np.sin(wd_rad)
|
|
v_calc = -ws * np.cos(wd_rad)
|
|
|
|
# 개별 성분 상대 오차 (분모 0 방지를 위해 abs(rec) > 0.1 인 경우만)
|
|
u_rel = np.abs(u_calc - df['uu']) / np.abs(df['uu']).replace(0, np.nan)
|
|
v_rel = np.abs(v_calc - df['vv']) / np.abs(df['vv']).replace(0, np.nan)
|
|
|
|
# 벡터 상대 오차 (Vector Relative Error: 오차 벡터 크기 / 실제 풍속)
|
|
vec_error_mag = np.sqrt((u_calc - df['uu'])**2 + (v_calc - df['vv'])**2)
|
|
vec_rel_error = vec_error_mag / ws
|
|
|
|
# 결과 수집
|
|
df['u_rel_err'] = u_rel
|
|
df['v_rel_err'] = v_rel
|
|
df['vec_rel_err'] = vec_rel_error
|
|
|
|
all_rel_errors.append(df[['u_rel_err', 'v_rel_err', 'vec_rel_err']])
|
|
|
|
# 2. 통계 계산
|
|
total_df = pd.concat(all_rel_errors)
|
|
|
|
print("[상대 오차(Relative Error) 분석 결과]")
|
|
print("-" * 40)
|
|
print(f"1. U 성분 평균 상대오차: {total_df['u_rel_err'].mean() * 100:.2f}%")
|
|
print(f" U 성분 최대 상대오차: {total_df['u_rel_err'].max() * 100:.2f}%")
|
|
print("-" * 40)
|
|
print(f"2. V 성분 평균 상대오차: {total_df['v_rel_err'].mean() * 100:.2f}%")
|
|
print(f" V 성분 최대 상대오차: {total_df['v_rel_err'].max() * 100:.2f}%")
|
|
print("-" * 40)
|
|
print(f"3. 벡터 전체 평균 상대오차: {total_df['vec_rel_err'].mean() * 100:.2f}%")
|
|
print(f" 벡터 전체 최대 상대오차: {total_df['vec_rel_err'].max() * 100:.2f}%")
|
|
print("-" * 40)
|
|
|
|
# 오차가 큰 샘플 확인
|
|
df_sample = pd.read_csv(files[0])
|
|
df_sample['wd_rad'] = np.radians(df_sample['wd_10m'])
|
|
df_sample['u_calc'] = -df_sample['ws_10m'] * np.sin(df_sample['wd_rad'])
|
|
df_sample['u_diff'] = np.abs(df_sample['u_calc'] - df_sample['uu'])
|
|
df_sample['u_rel'] = df_sample['u_diff'] / np.abs(df_sample['uu'])
|
|
|
|
print("\n[상대 오차가 높게 나타나는 샘플 (U성분 기준)]")
|
|
print(df_sample.sort_values('u_rel', ascending=False)[['tm', 'wd_10m', 'ws_10m', 'uu', 'u_calc', 'u_rel']].head(5))
|