-
[2월 4주차-2/27(2)]📌2024년 국내 항공 노선 이용률 분석 🛫Why Not SW CAMP 5기/수업 기록 2025. 2. 27. 18:20
1. 들어가며 ✈️
최근 몇 년간 국내 항공 시장은 급변하고 있습니다. 코로나19 이후 항공 수요가 회복되면서 일부 인기 노선은 좌석 경쟁이 심화되고, 반면 수요가 낮은 노선은 운영에 어려움을 겪고 있습니다. 이에 따라 "어떤 노선이 가장 많이 이용되고, 어떤 노선의 수요가 부족한지" 분석하여 항공사 및 공항 운영자들이 최적화 전략을 세울 수 있도록 돕고자 합니다.
이번 분석에서는 2024년 1월~8월 국내 항공 여객 이용률 데이터를 활용하여 노선별 이용률을 비교하고, 항공사별 경쟁력을 평가하며, 수요 변화에 따른 최적화 방안을 모색했습니다.
2. 데이터 및 분석 과정 📊
🔹 데이터 수집 및 전처리
📌 데이터 출처: 2024년 1월~8월 국내 항공 노선 이용률 CSV 파일
📌 사용 기술: Python, Pandas, Matplotlib, Seaborn, MySQL데이터는 월별로 나누어져 있어 이를 하나의 데이터프레임으로 통합하고, 항공사 코드(예: KAL → 대한항공)를 실제 항공사명으로 변환하는 작업을 진행했습니다. 또한 결측값 제거 및 오류 데이터 수정을 거쳐 최종 데이터셋을 확보했습니다.
3. 주요 분석 결과 🔍
(1) 노선별 평균 이용률 분석

📌 전체 노선 평균 이용률: 🚀 81.2%
먼저, 노선별 평균 이용률을 계산하여 상위 10개 및 하위 10개 노선을 도출했습니다.
✅수요가 높은 노선 TOP 10
👉 가장 높은 이용률을 기록한 노선들은 주로 제주, 김포, 인천을 연결하는 주요 노선이었습니다.
이는 제주도를 오가는 여행 수요가 꾸준히 많다는 것을 의미합니다.
수요가 낮은 노선 BOTTOM 10
👉 반대로, 이용률이 낮은 노선들은 주로 지방 간 이동 노선이었습니다.
이는 해당 지역 간 항공 수요가 상대적으로 낮거나, 철도/도로 교통망이 대체 수단으로 작용하는 것으로 해석할 수 있습니다.
(2) 항공사별 경쟁력 분석

각 항공사들이 인기 노선에서 얼마나 높은 점유율을 보이는지 비교했습니다.
그 결과 저비용항공사(LCC)들이 높은 이용률을 보이며 제주 노선에서 경쟁력을 확보하는 것으로 보여졌습니다.
(3) 월별 항공 수요 변화

📌 성수기 이용률 증가: 여름철 여행 수요 증가로 인해 전체적으로 높은 이용률을 기록!
📌 비수기 이용률 하락: 평균 이용률 감소모든 항공사의 이용률이 급감하는 패턴을 보였지만 좌석 공급은 줄지 않았습니다.
항공사 운영 전략 조정이 필요하다고 보입니다.
4. 기대 효과 및 활용 방안 🚀
이번 분석 결과를 바탕으로 항공사 및 공항 운영 기관이 실질적으로 활용할 수 있는 방안을 도출했습니다.
1️⃣ 항공사 운영 최적화
✅ 노선별 최적 좌석 공급 및 항공편 조정 → 수익성 개선
✅ 성수기·비수기 탄력적 운항 전략 → 좌석 부족 문제 해소 및 수익 극대화2️⃣ 공항 정책 수립 지원
✅ 슬롯(Slot) 배분 최적화 → 인기 노선의 운항 횟수 확대
✅ 지방 공항 노선 활성화 → 저비용항공사(LCC) 지원 및 인센티브 제공3️⃣ 소비자 편익 증대
✅ 탄력 요금제 도입 → 성수기 조기 예매 할인, 비수기 특가 제공
✅ 지방 노선 서비스 개선 → 기내 서비스 강화 및 노선 홍보 확대
5. 결론 및 마무리
이번 분석을 통해 국내 항공 노선별 이용률의 차이를 확인하고, 항공사별 운영 방식 및 계절별 수요 변화를 반영한 최적화 전략을 제안했습니다.
✅ 인기 노선→ 좌석 공급 확대 및 추가 항공편 운항 고려
✅ 이용률 낮은 노선 (지방 노선) → 공항 정책 개선 및 신규 마케팅 전략 필요
✅ 항공사별 경쟁력 비교 → 저비용항공사의 성장 가능성이러한 분석 결과는 항공사와 공항 운영 기관이 보다 효율적인 운항 계획을 수립하는 데 기여할 수 있으며, 나아가 데이터 기반 의사결정을 통해 항공 산업의 경쟁력을 높이는 데 중요한 역할을 할 것으로 기대됩니다. 🚀
📌 마무리하며
이번 분석은 과거 데이터를 기반으로 한 인사이트 도출에 초점을 맞췄지만, 미래 예측 모델을 활용하면 더욱 정교한 수요 예측이 가능할 것입니다.
✈️ 국내 항공 산업이 더욱 효율적으로 운영되길 바라며, 앞으로도 다양한 데이터 분석을 통해 인사이트를 제공하겠습니다! 🚀
👁🗨 전체 코드
import pandas as pd import pymysql from sqlalchemy import create_engine pymysql.install_as_MySQLdb() import MySQLdb import matplotlib.pyplot as plt import seaborn as sns from matplotlib import font_manager, rc import platform if platform.system() == 'Darwin': rc('font', family = 'AppleGothic') elif platform.system() == 'Windows': path = 'c:/Windows/Fonts/malgun.ttf' font_name = font_manager.FontProperties(fname=path).get_name() rc('font', family=font_name) else: print("sorry") # 데이터 불러오기 flights = [] for i in range(1, 9): df = pd.read_csv(f'data/2024년 {i}월 국내노선 여객 이용률.csv') # 파일 읽기 df['월'] = i flights.append(df) # 하나의 데이터프레임으로 합치기 flight_data = pd.concat(flights, ignore_index=True) flight_data['항공사'].value_counts() airline_dict = { "KAL": "대한항공", "AAR": "아시아나", "JJA": "제주항공", "JNA": "진에어", "ABL": "에어부산", "ASV": "에어서울", "TWB": "티웨이항공", "EOK": "에어로케이", "ESR": "이스타항공" } # 항공사 코드 변환 flight_data['항공사'] = flight_data['항공사'].replace(airline_dict) flight_data['항공사'].value_counts() flight_data=flight_data.dropna() flight_data['노선'] = flight_data['노선'].str.strip() flight_data.loc[(flight_data["노선"] == "김포-제주") & (flight_data["항공사"] == "이스타항공"), "좌석수"] = 89091 # -------------------------------------------------------------------------------------------- # 전처리된 데이터 mysql에 저장 host = 'localhost' user = 'root' password = 'rubi' db='test' charset='utf8' engine = create_engine(f'mysql+mysqldb://{user}:{password}@{host}/{db}') conn = engine.connect() flight_data.to_sql(name='flight', con=engine, if_exists='replace', index=False) conn.close() # -------------------------------------------------------------------------------------------- # 노선별 이용률 평균 분석: 전체 노선의 평균 이용률을 계산하여 수요가 높은 노선과 낮은 노선 구분 overall_avg = flight_data['이용률'].mean() print("전체 노선 평균 이용률:", overall_avg) route_mean = flight_data.groupby('노선')['이용률'].mean().reset_index() route_mean.columns = ['노선', '평균이용률'] top10 = route_mean.sort_values(by='평균이용률', ascending=False).head(10) bottom10 = route_mean.sort_values(by='평균이용률', ascending=True).head(10) # 시각화 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6), sharey=True) # Y축 공유 # 수요가 높은 노선 (TOP 10) sns.barplot(x='노선', y='평균이용률', data=top10, palette='Blues_r', ax=ax1) ax1.set_title('수요가 높은 노선 TOP 10', fontsize=14) ax1.set_xlabel('노선', fontsize=12) ax1.set_ylabel('평균 이용률 (%)', fontsize=12) ax1.tick_params(axis='x', rotation=45) # X축 라벨 회전 ax1.axhline(y=overall_avg, color='red', linestyle='--', label=f'전체 평균 ({overall_avg:.2f}%)') ax1.legend() # 수요가 낮은 노선 (BOTTOM 10) sns.barplot(x='노선', y='평균이용률', data=bottom10, palette='Reds_r', ax=ax2) ax2.set_title('수요가 낮은 노선 BOTTOM 10', fontsize=14) ax2.set_xlabel('노선', fontsize=12) ax2.tick_params(axis='x', rotation=45) ax2.axhline(y=overall_avg, color='red', linestyle='--', label=f'전체 평균 ({overall_avg:.2f}%)') ax2.legend() plt.tight_layout() plt.show() # -------------------------------------------------------------------------------------------- # 수요가 높은 상위 10개 노선에서의 항공사별 이용률 비교를 통해 경쟁력 평가 # (노선, 항공사) 별 평균 이용률 airline_mean = flight_data.groupby(['노선', '항공사'])['이용률'].mean().reset_index() # 수요가 높은 상위 10개 노선 추출 filtered_data1 = airline_mean[airline_mean['노선'].isin(top10['노선'])] # 시각화 plt.figure(figsize=(16, 5)) ax=sns.barplot(x='노선', y='이용률', hue='항공사', data=filtered_data1, palette='Paired', order=top10['노선']) plt.title('항공사별 노선 이용률 비교 (수요 상위 10개 노선)', fontsize=16) plt.xlabel('노선', fontsize=12) plt.ylabel('평균 이용률 (%)', fontsize=12) plt.legend(title='항공사') plt.ylim(70, 100) # y축 범위를 60~100%로 제한 legend = plt.legend(title='항공사' , prop={'size': 8}, ncol=5) legend.get_frame().set_alpha(0.3) # x축 눈금 위치 가져오기 xticks_positions = [tick.get_position()[0] for tick in ax.get_xticklabels()] # 막대 사이 위치에 세로선 추가 for x in range(len(xticks_positions) - 1): mid_point = (xticks_positions[x] + xticks_positions[x + 1]) / 2 plt.axvline(mid_point, color='gray', linestyle='--', linewidth=0.5, alpha=0.6) plt.show() # -------------------------------------------------------------------------------------------- # 항공사별 월별 평균 이용률과 그에 따른 좌석수 시각화 # 항공사별 월별 평균 이용률 airline_monthly_usage = flight_data.groupby(['항공사', '월'])['이용률'].mean().reset_index() # 항공사별 월별 총 좌석 수 airline_monthly_seats = flight_data.groupby(['항공사', '월'])['좌석수'].sum().reset_index() # 그래프 그리기 fig, axes = plt.subplots(2, 1, figsize=(12, 10), sharex=True) # 월별 이용률 (항공사별) sns.lineplot(data=airline_monthly_usage, x='월', y='이용률', hue='항공사', marker='o', ax=axes[0]) axes[0].set_title('항공사별 월별 평균 이용률') axes[0].set_ylabel('평균 이용률 (%)') axes[0].legend(title='항공사', bbox_to_anchor=(1.005, 1), loc='upper left') axes[0].grid(True, linestyle='--', alpha=0.5) # 월별 좌석 수 (항공사별) sns.lineplot(data=airline_monthly_seats, x='월', y='좌석수', hue='항공사', marker='o', ax=axes[1]) axes[1].set_title('항공사별 월별 좌석 수') axes[1].set_ylabel('좌석 수') axes[1].set_xlabel('월') axes[1].ticklabel_format(style='plain', axis='y') axes[1].grid(True, linestyle='--', alpha=0.5) axes[1].legend().remove() plt.tight_layout() plt.show()'Why Not SW CAMP 5기 > 수업 기록' 카테고리의 다른 글
[3월 1주차-3/4]SQL 프로그래밍 : 스토어드 프로시저, 함수, 인덱스, 뷰, 트리거 활용법 (0) 2025.03.04 [2월 4주차-2/28]항공 데이터 분석: 지연 패턴과 인사이트 도출💦 (0) 2025.02.28 [2월 4주차-2/27(1)]다양한 SQL 함수 정리 (0) 2025.02.27 [2월 4주차-2/26(2)]MySQL 연동하기: Python으로 MySQL 데이터 가져오기+실습 (0) 2025.02.26 [2월 4주차-2/26(1)]SQL JOIN과 서브쿼리 정리 (0) 2025.02.26