Python数据分析实战:机场客流数据抓取、清洗与可视化全流程
这次我们来看一个关于国内机场客流数据与暑期旅游需求的分析项目。这个项目并非传统的软件工具或AI模型而是一个基于公开数据源如民航局、机场官网、第三方数据平台进行数据抓取、清洗、分析和可视化的数据分析实践案例。它的核心价值在于通过自动化脚本或分析工具实时追踪并解读像“浦东机场周客流量反超广州白云”、“11座机场客流集体暴涨”这样的市场热点为旅游、交通、投资乃至个人出行决策提供数据支撑。对于技术开发者、数据分析师或对民航数据感兴趣的爱好者而言这个项目的重点不在于算法有多复杂而在于其数据获取的稳定性、分析的时效性、可视化呈现的直观性以及结论的启发性。本文将拆解如何构建这样一个分析流程从数据源选择与抓取到数据清洗与计算如周环比、同比再到关键指标如“浦东反超广州”的判定与可视化最后解读“暑期出游需求旺盛”背后的数据逻辑。整个过程会涉及Python数据处理、可能的API调用、数据可视化以及分析报告生成适合希望将数据技能应用于实际业务场景的读者。1. 核心能力速览能力项说明项目类型数据抓取、清洗、分析与可视化项目核心数据国内主要机场如浦东、白云、首都等的周度/月度旅客吞吐量关键技术栈Python (Pandas, Requests, BeautifulSoup, Matplotlib/Plotly) 可能涉及公开API或爬虫硬件门槛无特殊要求普通电脑即可运行数据分析量级对CPU/内存压力小核心产出1. 机场客流排名变化时序图2. 关键指标对比如浦东 vs 广州3. 客流增长率热力图或柱状图4. 自动化的分析报告摘要适合场景市场趋势分析、投资研究、出行规划参考、数据分析技能练手2. 适用场景与使用边界这个数据分析项目主要适用于以下几类人群和场景行业分析师与研究者持续监控民航业复苏态势、区域经济活力为行业报告提供数据佐证。旅游与交通相关企业洞察暑期、黄金周等旺季的出行需求波动辅助运力调配、营销策略制定。投资机构与个人投资者关注机场、航空、旅游板块客流数据是重要的先行或同步指标。数据爱好者与学习者作为一个完整的、有实际意义的练手项目涵盖从数据获取到洞察的全流程。使用边界与注意事项数据准确性分析结论高度依赖原始数据的准确性和及时性。必须明确数据来源并了解其可能的统计口径差异如是否包含国际中转。结论局限性客流增长受多种因素影响如假期、天气、重大活动、航线调整。数据分析可揭示相关性但需结合其他信息进行归因分析避免单一数据定论。合规抓取若通过爬虫获取数据必须严格遵守目标网站的robots.txt协议控制请求频率避免对对方服务器造成压力。优先使用官方或第三方提供的公开API接口。隐私与安全本项目分析的是宏观、聚合的客流数据不涉及任何个人隐私信息。在数据处理和存储过程中也无需接触个人信息。3. 环境准备与前置条件要复现或构建类似的分析项目你需要准备以下基础环境操作系统Windows 10/11, macOS, 或 Linux 发行版均可。Python 环境推荐使用 Python 3.8 及以上版本。使用conda或venv创建独立的虚拟环境是最佳实践。关键Python库数据处理pandas(核心)numpy数据获取requests(用于API调用)beautifulsoup4或lxml(用于网页解析如果需要爬虫)数据可视化matplotlib,seaborn, 或交互性更强的plotly报告生成jupyter notebook(用于交互分析) 也可以使用python-docx或markdown来生成静态报告数据源准备确定稳定可靠的数据来源。可能的渠道包括中国民航局定期发布的统计公报、各大机场上市公司发布的运营数据公告、第三方数据平台如航班管家、VariFlight等的公开报告或API。重要在使用任何API前请仔细阅读其使用条款、频率限制和授权方式。4. 数据获取与清洗流程这是项目的基石。我们以模拟获取周度机场客流数据为例展示一个通用流程。4.1 数据获取模拟示例假设我们从一个结构化的数据文件如CSV或一个简单的模拟API获取初始数据。在实际项目中你需要替换为真实的抓取代码。import pandas as pd import numpy as np # 模拟原始数据机场名称 周次 旅客吞吐量万人次 # 实际数据可能来自 API: response requests.get(https://api.example.com/airport-traffic) # 或爬虫解析HTML表格。 data { airport: [上海浦东, 广州白云, 北京首都, 深圳宝安, 成都天府, 重庆江北, 杭州萧山, 西安咸阳, 昆明长水, 南京禄口, 武汉天河] * 4, week_num: [202325, 202325, 202325, 202325, 202325, 202325, 202325, 202325, 202325, 202325, 202325, 202326, 202326, 202326, 202326, 202326, 202326, 202326, 202326, 202326, 202326, 202326, 202327, 202327, 202327, 202327, 202327, 202327, 202327, 202327, 202327, 202327, 202327, 202328, 202328, 202328, 202328, 202328, 202328, 202328, 202328, 202328, 202328, 202328], passengers: [185.2, 192.1, 178.5, 160.3, 155.8, 140.2, 135.6, 128.9, 125.4, 118.7, 112.5, 188.7, 189.5, 181.2, 163.8, 158.9, 143.1, 138.9, 132.1, 128.8, 121.5, 115.3, 190.5, 188.8, 183.9, 168.4, 162.5, 147.8, 142.1, 136.7, 132.9, 124.6, 119.8, 195.1, 191.2, 186.5, 172.3, 166.8, 152.4, 146.9, 141.2, 137.5, 128.3, 123.1] } df_raw pd.DataFrame(data) print(df_raw.head())4.2 数据清洗与转换原始数据往往需要清洗才能用于分析。# 1. 检查缺失值 print(f缺失值数量\n{df_raw.isnull().sum()}) # 2. 确保数据类型正确 df_raw[week_num] df_raw[week_num].astype(str) # 周次作为分类或时间标识 df_raw[passengers] pd.to_numeric(df_raw[passengers], errorscoerce) # 3. 创建更有意义的时间列示例将‘202328’转换为日期 # 这里简化处理实际可能需要根据周次计算具体日期范围 df_raw[week_label] W df_raw[week_num].str[-2:] (‘ df_raw[week_num].str[:4] ‘) # 4. 计算每个机场的周环比增长率 df_raw df_raw.sort_values([airport, week_num]) df_raw[passengers_prev_week] df_raw.groupby(airport)[passengers].shift(1) df_raw[week_over_week_growth] (df_raw[passengers] - df_raw[passengers_prev_week]) / df_raw[passengers_prev_week] * 100 # 5. 筛选出最新一周的数据用于排名分析 latest_week df_raw[week_num].max() df_latest df_raw[df_raw[week_num] latest_week].copy() df_latest df_latest.sort_values(passengers, ascendingFalse).reset_index(dropTrue) df_latest[rank] df_latest.index 1 print(f\n最新一周 ({latest_week}) 客流排名) print(df_latest[[rank, airport, passengers]].head())5. 核心分析浦东反超广州与集体暴涨基于清洗后的数据我们可以进行深度分析。5.1 关键指标判定“反超”逻辑实现“浦东190.5万反超广州”是一个动态排名变化事件。我们需要追踪多周数据来判断。# 选取浦东和广州的数据进行对比 airports_to_compare [上海浦东, 广州白云] df_comparison df_raw[df_raw[airport].isin(airports_to_compare)].pivot(indexweek_num, columnsairport, valuespassengers) df_comparison df_comparison.sort_index() # 按周次排序 # 计算每周的领先方及差距 df_comparison[leader] df_comparison.idxmax(axis1) df_comparison[gap] abs(df_comparison[上海浦东] - df_comparison[广州白云]) print(\n浦东 vs 广州 周度客流对比) print(df_comparison) # 判断是否发生反超 leader_sequence df_comparison[leader].tolist() for i in range(1, len(leader_sequence)): if leader_sequence[i] ! leader_sequence[i-1]: print(f\n*** 在第 {df_comparison.index[i]} 周{leader_sequence[i]} 反超了 {leader_sequence[i-1]} ***)5.2 “集体暴涨”量化分析“11座机场集体暴涨”需要定义一个增长阈值例如周环比增长率 5%并统计达到该阈值的机场数量。# 使用之前计算的 week_over_week_growth # 分析最新一周相对于前一周的增长情况 current_week latest_week prev_week str(int(latest_week) - 1) # 简化逻辑实际需处理周次进位 df_current df_raw[df_raw[week_num] current_week] df_prev df_raw[df_raw[week_num] prev_week] # 合并数据计算增长 df_growth pd.merge(df_current[[airport, passengers]], df_prev[[airport, passengers]], onairport, suffixes(_curr, _prev)) df_growth[growth_rate] (df_growth[passengers_curr] - df_growth[passengers_prev]) / df_growth[passengers_prev] * 100 # 定义“暴涨”阈值 surge_threshold 5.0 surge_airports df_growth[df_growth[growth_rate] surge_threshold] surge_count len(surge_airports) print(f\n在第 {current_week} 周周环比增长率超过 {surge_threshold}% 的机场有 {surge_count} 个) print(surge_airports[[airport, growth_rate]].round(2))6. 数据可视化呈现分析结果需要直观的图表来传达信息。6.1 使用Matplotlib绘制客流排名变化趋势import matplotlib.pyplot as plt import seaborn as sns plt.rcParams[font.sans-serif] [SimHei, DejaVu Sans] # 解决中文显示问题 plt.rcParams[axes.unicode_minus] False # 准备数据每个机场每周的排名 df_pivot df_raw.pivot(indexweek_num, columnsairport, valuespassengers) # 计算每周排名 weekly_rank df_pivot.rank(axis1, ascendingFalse, methodmin) weekly_rank weekly_rank.reset_index().melt(id_varsweek_num, var_nameairport, value_namerank) # 绘制重点机场排名趋势 focus_airports [上海浦东, 广州白云, 北京首都, 深圳宝安] df_focus weekly_rank[weekly_rank[airport].isin(focus_airports)] plt.figure(figsize(12, 6)) for airport in focus_airports: data df_focus[df_focus[airport] airport].sort_values(week_num) plt.plot(data[week_num], data[rank], markero, labelairport, linewidth2) plt.gca().invert_yaxis() # 排名第一在上方 plt.xlabel(周次) plt.ylabel(排名 (数字越小越好)) plt.title(重点机场周度客流排名变化趋势) plt.legend() plt.grid(True, linestyle--, alpha0.7) plt.tight_layout() plt.show()6.2 使用Seaborn绘制最新一周客流与增长气泡图# 合并最新一周的客流和增长数据 df_plot pd.merge(df_latest[[airport, passengers, rank]], df_growth[[airport, growth_rate]], onairport) plt.figure(figsize(14, 8)) scatter plt.scatter(df_plot[passengers], df_plot[rank], sdf_plot[growth_rate].abs()*20, # 气泡大小代表增长绝对值 cdf_plot[growth_rate], cmapRdYlGn, alpha0.7, edgecolorsblack, linewidth0.5) # 添加标注 for i, row in df_plot.iterrows(): plt.annotate(row[airport], (row[passengers], row[rank]), textcoordsoffset points, xytext(0,5), hacenter, fontsize9) plt.colorbar(scatter, label周环比增长率 (%)) plt.xlabel(旅客吞吐量 (万人次)) plt.ylabel(排名) plt.title(f第 {latest_week} 周机场客流排名 vs 吞吐量 (气泡大小增长率绝对值)) plt.gca().invert_yaxis() plt.grid(True, linestyle--, alpha0.3) plt.tight_layout() plt.show()7. 自动化报告生成与API服务设想对于需要定期产出的分析可以自动化生成报告。7.1 生成Markdown格式分析摘要def generate_markdown_report(df_latest, df_comparison, surge_airports, current_week): report f# 机场客流周度分析报告 (第 {current_week} 周) ## 核心发现 1. **榜首易主**本周{df_latest.iloc[0][airport]}机场以{df_latest.iloc[0][passengers]:.1f}万人次的客流量位居第一。 2. **增长势头**本周共有 **{len(surge_airports)}** 个机场周环比增长率超过5%呈现普涨态势。 3. **焦点对比**上海浦东与广州白云的竞争持续激烈本周领先方为 **{df_comparison.loc[current_week, leader]}**。 ## 详细数据 ### 本周客流Top 5 for _, row in df_latest.head().iterrows(): report f- {row[airport]}: {row[passengers]:.1f} 万人次 (排名第{row[rank]})\n report f ### 增长显著机场 (增长率 5%) for _, row in surge_airports.iterrows(): report f- {row[airport]}: {row[growth_rate]:.2f}%\n report ## 分析说明 本周数据反映出暑期出游需求旺盛带动主要机场客流集体攀升。具体分析需结合航线网络、节假日安排等因素。 return report markdown_report generate_markdown_report(df_latest, df_comparison, surge_airports, latest_week) print(markdown_report) # 可以将 report 写入文件 with open(weekly_airport_report.md, w, encodingutf-8) as f: f.write(markdown_report)7.2 构建简易数据查询APIFlask示例如果你希望将分析结果以服务形式提供可以构建一个简单的API。# 假设这是一个单独的 app.py 文件 from flask import Flask, jsonify, request import pandas as pd # ... (这里应包含之前的数据加载和预处理逻辑例如将 df_raw 加载到内存或数据库) app Flask(__name__) app.route(/api/airport/ranking/week_num, methods[GET]) def get_ranking(week_num): 获取指定周次的机场客流排名 # 从预处理的数据中筛选 df_week df_raw[df_raw[week_num] week_num] if df_week.empty: return jsonify({error: Week number not found}), 404 result df_week.sort_values(passengers, ascendingFalse)[[airport, passengers]].to_dict(records) return jsonify({week: week_num, ranking: result}) app.route(/api/airport/growth, methods[GET]) def get_growth(): 计算最新一周相对于前一周的增长情况 # ... 实现增长计算逻辑 latest df_raw[week_num].max() # 简化演示返回模拟数据 return jsonify({current_week: latest, growth_summary: {surge_count: len(surge_airports), top_grower: surge_airports.iloc[0][airport] if not surge_airports.empty else None}}) if __name__ __main__: # 注意生产环境请勿使用 debugTrue app.run(host127.0.0.1, port5000, debugFalse)启动服务后可以通过curl http://127.0.0.1:5000/api/airport/ranking/202328或编写Python客户端进行查询。8. 资源占用与性能考量此类数据分析项目对系统资源要求不高性能瓶颈主要出现在数据获取和初始清洗阶段。CPU/内存处理单周或单月全国主要机场数据几十行*几十列Pandas操作在几秒内完成内存占用通常小于100MB。网络I/O如果涉及爬虫或API调用这是主要的时间消耗点。务必添加请求间隔如time.sleep和错误重试机制。存储清洗后的结构化数据CSV/Parquet格式体积很小长期存储可按周/月分片。自动化调度若需每周自动运行可使用系统级的cronLinux/macOS或计划任务Windows或使用Python的schedule库、Airflow等更专业的工具。9. 常见问题与排查方法问题现象可能原因排查方式解决方案数据抓取失败/返回空1. 网站结构变更2. API接口更新或需要密钥3. IP被限制或请求频率过高1. 打印HTTP状态码和响应内容2. 检查网页源代码或API文档3. 使用浏览器开发者工具检查网络请求1. 更新解析逻辑XPath/CSS选择器2. 申请合法API密钥并遵循调用规范3. 降低请求频率添加User-Agent使用代理池谨慎合规使用数据分析结果异常如负增长过高1. 原始数据存在异常值或缺失2. 数据清洗逻辑有误如排序错误3. 周次计算逻辑错误跨年1. 检查df_raw.isnull().sum()2. 逐步打印中间数据框如分组后的shift结果3. 验证周次编号的连续性1. 清洗时填充或剔除异常值2. 仔细检查groupby、shift、merge等关键步骤3. 使用明确的日期列代替周次编号进行计算可视化图表中文乱码系统或Matplotlib未配置中文字体检查plt.rcParams[font.sans-serif]的设置确保列表中包含已安装的中文字体名称或指定字体文件路径环比增长率计算出现无限大(inf)前一周数据为0或缺失导致除零错误检查df_raw[passengers_prev_week]是否为0或NaN在计算前进行判断df[growth] df.apply(lambda row: (row[curr]-row[prev])/row[prev]*100 if row[prev]0 else np.nan, axis1)API服务无法启动或访问1. 端口被占用2. Flask应用代码错误3. 防火墙阻止1. 检查端口占用netstat -ano | findstr :50002. 查看Flask启动日志3. 检查本地防火墙设置1. 更换端口app.run(port5001)2. 根据日志修复代码错误3. 在防火墙中允许Python或指定端口10. 最佳实践与后续方向最佳实践数据源备份对爬取的原始网页或API响应进行快照保存便于回溯和调试。模块化代码将数据获取、清洗、分析、可视化、报告生成拆分为独立函数或模块提高可维护性。配置化管理将机场列表、增长阈值、API密钥、图表颜色等参数放在配置文件如config.yaml中。异常处理与日志在数据抓取和关键计算步骤添加try-except并记录详细的运行日志。版本控制使用Git管理代码和重要的分析脚本特别是数据清洗逻辑变更时。后续扩展方向数据深化接入航班量、准点率、货运量等多维度数据进行交叉分析。预测模型基于历史客流数据尝试使用时间序列模型如Prophet, LSTM进行短期客流预测。关联分析将机场客流与当地天气、旅游景区热度、重大事件等外部数据进行关联分析。实时仪表盘使用Plotly Dash或Streamlit构建交互式实时数据仪表盘动态展示排名变化和增长趋势。自动化报告推送将生成的Markdown报告通过邮件或企业微信/钉钉机器人自动发送给相关团队。这个项目展示了如何用技术手段将一则热点新闻“浦东反超广州11座机场暴涨”转化为一个可重复、可验证、可深化的数据分析流程。它不只是一个结论更是一个从数据到洞察的方法论实例。对于开发者而言价值在于掌握了这套方法就可以快速应对其他类似的数据分析需求。建议从获取一个可靠的公开数据源开始先跑通最小闭环再逐步增加分析的维度和自动化程度。