
주제 선정 배경
3월에서 4월사이 연인들의 필수데이트 코스 벚꽃놀이, 저도 벚꽃구경을 좋아해서 석촌호수 같은 곳으로 매년 구경 가곤 합니다. 올해도 여자친구랑 혜화 낙산공원에 가서 꽃구경을 하고 왔는데요. 벚꽃은 언제봐도 로맨틱하고 예쁜 것 같습니다.
근데 올해 벚꽃이 피자마자 비가 오더라구요. 그때 뭔가 매년 벚꽃시즌만 되면 비가 내리는 것 같다는 느낌이 딱 들었습니다.
벚꽃시즌만 되면 비가 내리는 것 같은 이 느낌이 그저 기분탓일지, 아니면 실제로도 비가 매번 내리는지.
한번 확인해보려고 합니다.
활용 데이터
- 벚꽃 개화시기 - 기상자료개방포털
- 1973년부터 현재까지 벚꽃의 발아, 개화, 만발 시기를 기록한 데이터다. 벚꽃이 언제 피어났는지 확인하기 위해 수집했다.
- 기상청_지상 일자료 조회서비스 API - 공공데이터포털
- 과거의 기상정보 데이터를 API 형식으로 제공해준다. 과거 비온날을 확인하기 위해 수집하였다.
분석 과정 및 결론

먼저 벚꽃 개화시기 데이터를 이용해서 개화일을 기준으로 +6일간의 일강수량 정보를 기상청 API를 통해 수집했다. 아래는 개화일을 기준으로 +6일간의 일강수량 데이터를 수집한 것이다. 개화시기를 선정한 이유는 만발시기 데이터에 15개의 결측치가 있었기 때문이다. 반면 개화시기는 모든 연도에 관측 데이터가 존재했다.

이후 두 데이터를 연결하여 만발일을 기준으로 1주일간 비가 내린적이 며칠인지를 계산했다. 계산할 때 0mm 이상 즉, 비가 조금이라도 내린 날과 5mm 이상 즉, 벚꽃 구경에 방해가 될만큼 비가 적당히 내린 날과 10mm 이상 즉, 벚꽃이 떨어질만큼 강한 비가 내린 날 총 3가지로 분류했다.

벚꽃시즌만 되면 비오는 것 같은 느낌이 기분탓이었는지 확인하기 위해 내가 벚꽃구경을 가기 시작한 연도인 2016년부터 2025년까지 데이터를 이용해 확인해봤다. 아래는 2016~2025년 개화시기 이후 1주일 이내에 조금이라도 비가 온 년도, 5mm 이상, 10mm 이상 온 년도에 "비" 표시를 이용해 각각 시각화한 것이다.



2016년 ~ 2025년 전체 10년 중 개화 이후 조금이라도 비가 내린 해는 8년, 벚꽃구경에 방해가 될 정도인 5mm 이상 비가 내린 해는 5년, 벚꽃이 떨어질 정도로 강한 비가 내리는 정도인 10mm이상 비가 내린 해는 4년 이었다.
벚꽃 시즌만 되면 비오는 것 같은 느낌은 기분탓이 아니라
실제로 비가 거의 매번 내렸었다.
쿠키
1973년부터 2025년까지 데이터를 살펴봤다.

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 조금이라도 비가 온 해는 44년 이었다. 즉, 대부분의 해에서 벚꽃 개화 이후 1주일 이내에 비가 내렸던 것을 알 수 있었다. 거의 매번 비가 조금이라도 왔다는 것이 놀라웠다.

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 벚꽃 구경에 방해가 되는 정도인 5mm이상 비가 온 해는 28년 이었다. 즉, 절반 정도의 해에서 벚꽃 개화 이후에 5mm 이상 비가 내렸던 것을 알 수 있었다.

1973년부터 현재까지 총 53년 중 벚꽃 개화 이후 1주일 이내에 벚꽃이 떨어질 정도인 10mm이상 비가 온 해는 23년 이었다. 즉, 전체 중 43% 정도의 해에서 벚꽃 개화 이후에 10mm 이상 비가 내렸던 것을 알 수 있었다.
마무리
벚꽃은 보통 3월 말 ~ 4월 초에 개화한다. 이 시기는 계절적으로 겨울철 고기압이 물러가고, 저기압과 봄비가 자주 찾아오는 시기라 비가 자주 내린다고 한다. 그래서 벚꽃 시즌이 되면 비가 자주 내린다고 생각했나보다. 그러므로 벚꽃이 피면 볼 수 있을 때 가서 봐야된다. 미루고 미루다 보면 비 때문에 그 해의 벚꽃을 놓칠지도 모른다.
최종코드
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests
from datetime import datetime, timedelta
from tqdm import tqdm
# 데이터 불러오기
data = pd.read_excel('/content/drive/MyDrive/공모전/블로그/벚꽂 데이터/개화시기.xlsx')
data = data[['지점', '년도', '발아', '개화', '만발']]
# 데이터 타입 변환
data['개화'] = pd.to_datetime(data['개화'])
# 결측치 처리
data.loc[data['만발'] == '결측', '만발'] = 'Na'
data.loc[data['만발'] == ' ', '만발'] = 'Na'
data.head()
# 개화시기 이후 1주일간의 일강수량 데이터 추출
rain_data = pd.DataFrame()
url = 'http://apis.data.go.kr/1360000/AsosDalyInfoService/getWthrDataList'
for date in tqdm(data['개화']):
startDt = date.strftime('%Y%m%d')
endDt = (date + timedelta(days=6)).strftime('%Y%m%d')
params ={
'serviceKey' : 'API_KEY', #API 키 입력
'pageNo' : '1',
'numOfRows' : '10',
'dataType' : 'JSON',
'dataCd' : 'ASOS',
'dateCd' : 'DAY',
'startDt' : startDt,
'endDt' : endDt,
'stnIds' : '108'
}
response = requests.get(url, params=params)
response = response.json()
날짜_list = []
일강수량_list = []
# 강수량 데이터 추출
for idx in range(len(response['response']['body']['items']['item'])):
날짜_list.append(response['response']['body']['items']['item'][idx]['tm'])
일강수량_list.append(response['response']['body']['items']['item'][idx]['sumRn'])
df = pd.DataFrame({
'날짜' : 날짜_list,
'일강수량' : 일강수량_list
})
rain_data = pd.concat([rain_data, df])
# 기상 데이터 전처리
rain_data = rain_data.reset_index(drop = True)
rain_data['날짜'] = pd.to_datetime(rain_data['날짜'])
rain_data.loc[rain_data['일강수량'] == '', '일강수량'] = 0
rain_data['일강수량'] = rain_data['일강수량'].astype('float')
rain_data.head()
# 강우일수 계산
data['개화이후강우일수'] = 0
data['개화이후10mm이상강우일수'] = 0
for idx in range(len(data)):
tmp = rain_data.loc[rain_data['날짜'].dt.year == data['개화'][idx].year]
data.loc[idx, '개화이후강우일수'] = len(tmp.loc[tmp['일강수량'] > 0])
data.loc[idx, '개화이후10mm이상강우일수'] = len(tmp.loc[tmp['일강수량'] >= 10])
data.head()
# 2016 ~ 2025년 데이터 추출
df = data.copy()
df = df.loc[df['년도'] >= 2016]
df['강우여부'] = df['개화이후강우일수'] != 0
# 시각화
fig, ax = plt.subplots(figsize=(10, 2))
ax.set_xlim(min(df['년도']) - 1, max(df['년도']) + 1)
ax.set_ylim(0, 1)
ax.axis('off') # 축 숨기기
for idx, row in df.iterrows():
x = row['년도']
flower_icon = "꽃"
rain_icon = "비" if row['강우여부'] else ""
ax.text(x, 0.6, flower_icon, ha='center', fontsize=18)
ax.text(x, 0.3, rain_icon, ha='center', fontsize=18)
ax.text(x, 0, str(x), ha='center', fontsize=10)
plt.title("벚꽃 개화 이후 1주일 이내 조금이라도 비가 온 해", fontsize=14)
plt.tight_layout()
plt.show()
# 전체 데이터 이용
df = data.copy()
df['강우여부'] = df['개화이후강우일수'] != 0
# 시각화
fig, ax = plt.subplots(figsize=(22, 2))
ax.set_xlim(min(df['년도']) - 1, max(df['년도']) + 1)
ax.set_ylim(0, 1)
ax.axis('off') # 축 숨기기
for idx, row in df.iterrows():
x = row['년도']
flower_icon = "꽃"
rain_icon = "비" if row['강우여부'] else ""
ax.text(x, 0.6, flower_icon, ha='center', fontsize=18)
ax.text(x, 0.3, rain_icon, ha='center', fontsize=18)
ax.text(x, 0, str(x), ha='center', fontsize=10)
plt.title("벚꽃 개화 이후 1주일 이내 0mm 이상 비가 온 해", fontsize=14)
plt.tight_layout()
plt.show()'데이터분석 > 일상' 카테고리의 다른 글
| 나는 언제 배달음식을 시켜 먹을까? 실제 배달주문 데이터로 알아본 배달 땡기는 날 (2) | 2025.06.08 |
|---|---|
| 음식맛을 가르는 결정적인 한 끗, 음식별 킥이 되는 재료는 무엇일까? (3) | 2025.05.25 |
| 이 도시는 뭐가 유명하지? 여행계획 짜기 귀찮아서 만들어본 검색량 기반 꾸준히 인기있는 관광지 찾기 (4) | 2025.05.18 |
| 일주일 중 직장인이 가장 우울한 요일은 언제일까? 퇴사 마려운 요일을 알아보자 (0) | 2025.05.04 |
| 영상보다 댓글이 먼저인 시대, 댓글을 먼저 보는 행동이 위험하진 않을까? (3) | 2025.04.27 |