전국 산 위치정보.xlsx
2020 전국산불데이터.xlsx
2021 전국산불데이터.xlsx
2022 전국산불데이터.xlsx
2023 전국산불데이터.xlsx
최단거리 산 찾기.ipynb
최단거리 산 기상데이터.ipynb
발생시간별 기상 데이터 가져오기 .ipynb
20~23 전국 산불 데이터 총합.xlsx
# 최단거리 산 찾기
import pandas as pd
from geopy.distance import geodesic
# 파일 경로 설정
fire_data_path = r'C:\\Users\\ASUS\\SAI\\2024 전국산불데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'
output_path = r'C:\\Users\\ASUS\\SAI\\전국_가장_가까운_산_결과_2024.xlsx'
# 데이터 읽기
fire_data = pd.read_excel(fire_data_path)
mountain_data = pd.read_excel(mountain_data_path)
# 필요한 컬럼 이름 확인 후, 가정: 산불 데이터에 '위도', '경도', 산 데이터에 '산 이름', '위도', '경도'가 존재
fire_locations = fire_data[['발생연월일', '위도', '경도']].dropna().reset_index(drop=True)
mountain_locations = mountain_data[['산이름', '위도', '경도']].dropna().reset_index(drop=True)
# 결과를 저장할 리스트 초기화
results = []
# 산불 위치별 가장 가까운 산 찾기
for idx, fire in fire_locations.iterrows():
where = fire['발생연월일']
fire_coord = (fire['위도'], fire['경도'])
closest_mountain = None
closest_distance = float('inf')
for _, mountain in mountain_locations.iterrows():
mountain_coord = (mountain['위도'], mountain['경도'])
distance = geodesic(fire_coord, mountain_coord).kilometers
if distance < closest_distance:
closest_distance = distance
closest_mountain = mountain['산이름']
# 결과 저장
results.append({
'산불_발생시기': where,
'산불_위도': fire['위도'],
'산불_경도': fire['경도'],
'가장_가까운_산': closest_mountain,
'거리(km)': closest_distance
})
# 결과를 데이터프레임으로 변환
result_df = pd.DataFrame(results)
# 엑셀 파일로 저장
result_df.to_excel(output_path, index=False)
print(f"결과가 '{output_path}' 파일로 저장되었습니다.")
#최단거리 산 기상데이
import pandas as pd
from geopy.distance import geodesic
# 파일 경로 설정
whether_data_path = r'C:\\Users\\ASUS\\SAI\\2024 강원산불 기상데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\가장_가까운_산_결과_2024.xlsx'
output_path = r'C:\\Users\\ASUS\\SAI\\2024 가장 가까운산 기상데이터 어쩌구.xlsx'
# 데이터 읽기
whether_data = pd.read_excel(whether_data_path)
mountain_data = pd.read_excel(mountain_data_path)
# 필요한 컬럼 이름 확인 후, 가정: 산불 데이터에 '위도', '경도', 산 데이터에 '산 이름', '위도', '경도'가 존재
whether_locations = whether_data[['발생시간','산이름','기압','기온','10m 풍속','2m 풍속', '2미터 습도']].dropna().reset_index(drop=True)
mountain_locations = mountain_data[['산불_발생시기', '가장_가까운_산']].dropna().reset_index(drop=True)
# 결과를 저장할 리스트 초기화
results = []
# 산불 위치별 가장 가까운 산 찾기
for idx, whether in whether_locations.iterrows():
when = whether['발생시간']
where = whether['산이름']
air_t = None
air_p = None
air_s10 = None
air_s2 = None
suup_2 = None
for _, mountain in mountain_locations.iterrows():
if whether['발생시간'] == mountain['산불_발생시기'] :
if whether['산이름'] == mountain['가장_가까운_산'] :
air_t = whether['기온']
air_p = whether['기압']
air_s10 = whether['10m 풍속']
air_s2 = whether['2m 풍속']
suup_2 = whether['2미터 습도']
else :
continue
else :
continue
# 결과 저장
results.append({
'발생시기': when,
'발생위치' : where,
'기온' : air_t,
'기압' : air_p,
'풍속 10m': air_s10,
'풍속 2m': air_s2,
'습도 2m': suup_2
})
# 결과를 데이터프레임으로 변환
result_df = pd.DataFrame(results)
result_df.dropna(axis='index', how = 'any', inplace = True)
result_df
# 엑셀 파일로 저장
result_df.to_excel(output_path, index=False)
print(f"결과가 '{output_path}' 파일로 저장되었습니다.")
# 발생시간 기상 데이터 가져오기
import requests
from xml.etree import ElementTree as ET
import pandas as pd
import time # 요청 간 대기 시간 추가를 위해 사용
# API 키
SKEY = '04ivMBs+T+/URYubuW0VoEysuWeCU4Oj2pts0CujIh1h3rcbtP2XmmgCOmIhHyBRGI1uGJEBhrY0cuac9lHz0w=='
# 강원 지역의 산불 데이터를 필터링하고 발생 시간 컬럼을 추가하는 함수
def get_fire_data(file_path):
ffire_data = pd.read_excel(file_path).dropna().reset_index(drop=True) # 파일 경로의 데이터를 불러옴
# 발생시간 컬럼 생성 (예: 202311021632) -> YYYYMMDDHHMM 형식
ffire_data['발생시간'] = ffire_data.apply(
lambda x: f"{x['발생연']:04}{x['발생월']:02}{x['발생일']:02}", axis=1
)
return ffire_data
# 특정 발생 시간에 맞는 기상 데이터를 API에서 가져오는 함수
def get_weather_data(time_str):
url = '<http://apis.data.go.kr/1400377/mtweather/mountListSearch>'
params = {
'serviceKey': SKEY,
'numOfRows': '1000',
'pageNo': '1',
'_type': 'xml',
'localArea': '10',
'tm': time_str
}
response = requests.get(url, params=params)
print(f"Requesting data for {time_str}... Status: {response.status_code}")
if response.status_code == 200:
root = ET.fromstring(response.content)
data = []
for item in root.findall('.//item'):
data.append({
'발생시간': time_str,
'산이름': item.find('obsname').text if item.find('obsname') is not None else None,
'관측시간': item.find('tm').text if item.find('tm') is not None else None,
'기압': item.find('pa').text if item.find('pa') is not None else None,
'기온': item.find('tm2m').text if item.find('tm2m') is not None else None,
'10m 풍향': item.find('wd10m').text if item.find('wd10m') is not None else None,
'10m 풍속': item.find('ws10m').text if item.find('ws10m') is not None else None,
'2m 풍향': item.find('wd2m').text if item.find('wd2m') is not None else None,
'2m 풍속': item.find('ws2m').text if item.find('ws2m') is not None else None,
'2m 풍향str': item.find('wd2mstr').text if item.find('wd2mstr') is not None else None,
'2미터 습도': item.find('hm2m').text if item.find('hm2m') is not None else None,
})
# 데이터가 없으면 알림
if not data:
print(f"No data returned for {time_str}")
return data
else:
print(f"Failed to retrieve data for {time_str}: Status code {response.status_code}")
return [] # 데이터가 없는 경우 빈 리스트 반환
# 산불 데이터 파일에서 발생 시간을 불러와 강원 지역 산불 발생 시간에 맞는 기상 데이터를 추출하고 하나의 파일로 저장
file_path = r'C:\\Users\\ASUS\\SAI\\2021 전국산불데이터.xlsx' # 산불 데이터 파일 경로
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'
fire_data = get_fire_data(file_path)
close_mountain = get_colsest_monutain(mountain_data_path)
'''
# 전체 기상 데이터를 누적할 리스트 생성
all_weather_data = []
# 강원 지역의 각 발생 시간에 맞는 기상 데이터를 리스트에 추가
for time_str in fire_data['발생시간']:
weather_data = get_weather_data(time_str)
if weather_data: # 데이터가 있는 경우만 누적
all_weather_data.extend(weather_data)
time.sleep(1) # API 요청 간 대기 시간 추가
# 누적된 데이터를 데이터프레임으로 변환
all_weather_df = pd.DataFrame(all_weather_data)
all_weather_df
'''
# 엑셀 파일로 저장 (with 문을 사용)
#output_path = r'C:\\Users\\ASUS\\SAI\\2024 강원산불 기상데이터.xlsx'
#with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# all_weather_df.to_excel(writer, index=False)
#print("完了")
산불데이터 넣으면 최근접 관측소 기상데이터 뽑기
import requests
from xml.etree import ElementTree as ET
import pandas as pd
import time
from geopy.distance import geodesic
# API 키
SKEY = '04ivMBs+T+/URYubuW0VoEysuWeCU4Oj2pts0CujIh1h3rcbtP2XmmgCOmIhHyBRGI1uGJEBhrY0cuac9lHz0w=='
# 강원 지역 산불 데이터를 처리하는 함수
def get_fire_data(file_path):
ffire_data = pd.read_excel(file_path).dropna().reset_index(drop=True)
ffire_data['발생시간'] = ffire_data.apply(
lambda x: f"{x['발생연']:04}{x['발생월']:02}{x['발생일']:02}{x['발생시'][:2]}{x['발생시'][3:5]}", axis=1
)
ffire_data['발생시간'] = ffire_data['발생시간'].apply(lambda x: x[:-1] + '0')
# 지역코드 매핑 사전
region_code_map = {
"서울": "01",
"세종": "02",
"부산": "03",
"대구": "04",
"광주": "05",
"인천": "06",
"대전": "07",
"울산": "08",
"경기": "09",
"강원": "10",
"충남": "11",
"충북": "12",
"전남": "13",
"전북": "14",
"경남": "15",
"경북": "16",
"제주": "17"
}
# 지역코드 설정
ffire_data['지역코드'] = ffire_data['시'].apply(
lambda x: region_code_map.get(x, "알수없음") # 매핑되지 않는 경우 "알수없음" 처리
)
print(f"✅ 산불 데이터 로드 완료: {len(ffire_data)}건의 데이터")
return ffire_data
# 특정 시간의 기상 데이터를 가져오는 함수
def get_weather_data(time_str,loc_str):
url = '<http://apis.data.go.kr/1400377/mtweather/mountListSearch>'
params = {
'serviceKey': SKEY,
'numOfRows': '1000',
'pageNo': '1',
'_type': 'xml',
'localArea': loc_str,
'tm': time_str
}
try:
response = requests.get(url, params=params, timeout=10) # 타임아웃 설정
if response.status_code == 200:
root = ET.fromstring(response.content)
data = []
for item in root.findall('.//item'):
data.append({
'발생시간': time_str,
'산이름': item.find('obsname').text if item.find('obsname') is not None else None,
'관측시간': item.find('tm').text if item.find('tm') is not None else None,
'기압': item.find('pa').text if item.find('pa') is not None else None,
'기온': item.find('tm2m').text if item.find('tm2m') is not None else None,
'10m 풍향': item.find('wd10m').text if item.find('wd10m') is not None else None,
'10m 풍속': item.find('ws10m').text if item.find('ws10m') is not None else None,
'2m 풍향': item.find('wd2m').text if item.find('wd2m') is not None else None,
'2m 풍속': item.find('ws2m').text if item.find('ws2m') is not None else None,
'2m 풍향str': item.find('wd2mstr').text if item.find('wd2mstr') is not None else None,
'2미터 습도': item.find('hm2m').text if item.find('hm2m') is not None else None,
})
return data
else:
print(f"❌ {time_str} 데이터 요청 실패: HTTP {response.status_code}")
return []
except requests.exceptions.Timeout:
print(f"⚠️ {time_str} 데이터 요청 시간 초과")
return []
except requests.exceptions.RequestException as e:
print(f"⚠️ {time_str} 데이터 요청 실패: {e}")
return []
# 산불 위치에서 가장 가까운 산을 찾는 함수
def get_closest_mountain(fire_data, mountain_data_path):
mountain_data = pd.read_excel(mountain_data_path)
fire_locations = fire_data[['발생시간', '위도', '경도']].dropna().reset_index(drop=True)
mountain_locations = mountain_data[['산이름', '위도', '경도']].dropna().reset_index(drop=True)
results = []
for idx, fire in fire_locations.iterrows():
fire_coord = (fire['위도'], fire['경도'])
closest_mountain = None
closest_distance = float('inf')
for _, mountain in mountain_locations.iterrows():
mountain_coord = (mountain['위도'], mountain['경도'])
distance = geodesic(fire_coord, mountain_coord).kilometers
if distance < closest_distance:
closest_distance = distance
closest_mountain = mountain['산이름']
results.append({
'발생시간': fire['발생시간'],
'위도': fire['위도'],
'경도': fire['경도'],
'가장 가까운 산': closest_mountain,
'거리(km)': closest_distance
})
return pd.DataFrame(results)
# 데이터 경로
file_path = r'C:\\Users\\ASUS\\SAI\\2023 전국산불데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'
# 데이터 로드
fire_data = get_fire_data(file_path)
closest_mountain_df = get_closest_mountain(fire_data, mountain_data_path)
# 기상 데이터 추출 및 병합
all_weather_data = []
total_requests = len(fire_data) # 전체 요청 수
# zip으로 두 컬럼을 동시에 순회
for idx, (time_str, loc_str) in enumerate(zip(fire_data['발생시간'], fire_data['지역코드'])):
progress = ((idx + 1) / total_requests) * 100
print(f"🚀 진행 중: {idx + 1}/{total_requests} ({progress:.2f}%) - {time_str}, 지역코드: {loc_str}")
# 해당 발생 시간의 가장 가까운 산 이름 가져오기
closest_mountain_name = closest_mountain_df[closest_mountain_df['발생시간'] == time_str]['가장 가까운 산'].values[0]
# 기상 데이터 요청
weather_data = get_weather_data(time_str, loc_str) # time_str과 loc_str을 함수에 전달
# 가장 가까운 산의 데이터만 필터링
if weather_data:
filtered_data = [w for w in weather_data if w['산이름'] == closest_mountain_name]
all_weather_data.extend(filtered_data)
print(f"✅ {time_str} - {closest_mountain_name} 데이터 추가됨")
else:
print(f"⚠️ {time_str}에 대한 데이터 없음")
time.sleep(1) # 요청 간 대기
# 데이터프레임 생성 및 병합
weather_df = pd.DataFrame(all_weather_data)
final_df = pd.merge(closest_mountain_df, weather_df, on='발생시간', how='inner') # 가장 가까운 산의 데이터만 유지
# 결과 저장
output_file = '2023_산불_기상_데이터_가까운_산.xlsx'
final_df.to_excel(output_file, index=False)
print(f"✅ 데이터가 '{output_file}'로 저장되었습니다!")