加拿大省域降水JSON数据处理代码优化及可视化技术问询
问题解决:降水极值数据分组优化与可视化方案
一、代码优化:高效构建年份-降水极值字典
你的原始代码存在严重性能问题:内层循环中每次都要遍历整个X数组生成对应年份的降水列表,外层还重复遍历X,时间复杂度达到O(n²*m)(n为数据条数,m为年份数),数据量增大后会急剧变慢。
优化方案:单次遍历完成分组
仅需遍历一次所有数据,直接按年份将降水值追加到对应列表中,时间复杂度降至O(n),效率提升显著。
优化后代码:
import json from collections import defaultdict # 读取JSON数据 with open('items.json') as f: data = json.load(f) # 直接构建目标字典 record_precp = defaultdict(list) for feat in data['features']: props = feat['properties'] year = props['RECORD_PRECIPITATION_YR'] precip = props['RECORD_PRECIPITATION'] record_precp[year].append(precip) # 如需转换为普通字典(可选) # record_precp = dict(record_precp)
代码说明:
- 用
collections.defaultdict自动初始化年份对应的空列表,省去判断年份是否存在的步骤 - 仅遍历一次
features数组,直接将每个降水值追加到对应年份的列表中 - 无需额外提取
X数组和去重年份列表,一步完成分组
二、可视化方案:从单年份到多维度分析
针对年份对应大量降水数据的场景,以下几种可视化方案能更全面展示数据特征:
1. 多年份箱线图对比
将所有年份的降水极值分布放在同一图中,直观对比逐年的分布差异、异常值变化。
import matplotlib.pyplot as plt import numpy as np # 按年份排序 sorted_years = sorted(record_precp.keys()) precip_data = [record_precp[year] for year in sorted_years] plt.figure(figsize=(15, 8)) plt.boxplot(precip_data, labels=sorted_years) plt.xticks(rotation=90) plt.xlabel('年份') plt.ylabel('降水极值') plt.title('曼尼托巴省逐年降水极值分布') plt.tight_layout() plt.show()
2. 趋势线+箱线组合图
结合每年降水极值的中位数(或均值)趋势线,同时保留箱线图展示分布细节,兼顾趋势和离散程度。
import seaborn as sns import pandas as pd sorted_years = sorted(record_precp.keys()) # 整理为DataFrame方便seaborn处理 df = pd.DataFrame([(year, precip) for year in sorted_years for precip in record_precp[year]], columns=['年份', '降水极值']) plt.figure(figsize=(15, 8)) # 绘制箱线图 sns.boxplot(x='年份', y='降水极值', data=df, color='lightblue') # 计算每年中位数并绘制趋势线 year_medians = df.groupby('年份')['降水极值'].median() plt.plot(sorted_years, year_medians, color='red', marker='o', label='中位数趋势') plt.xticks(rotation=90) plt.legend() plt.title('降水极值分布与中位数趋势') plt.tight_layout() plt.show()
3. 小提琴图:展示分布密度
小提琴图比箱线图更直观展示数据的分布密度,适合观察不同年份降水极值的集中趋势。
plt.figure(figsize=(15, 8)) sns.violinplot(x='年份', y='降水极值', data=df, inner='quartile') plt.xticks(rotation=90) plt.xlabel('年份') plt.ylabel('降水极值') plt.title('曼尼托巴省逐年降水极值密度分布') plt.tight_layout() plt.show()
4. 月份维度热力图(若数据含月份信息)
如果properties中的LOCAL_MONTH字段可用,可按年份-月份分组,绘制热力图展示不同月份的降水极值变化。
# 重新整理数据,包含月份信息 df_with_month = pd.DataFrame() for feat in data['features']: props = feat['properties'] df_with_month = pd.concat([df_with_month, pd.DataFrame({ '年份': props['RECORD_PRECIPITATION_YR'], '月份': props['LOCAL_MONTH'], '降水极值': props['RECORD_PRECIPITATION'] }, index=[0])], ignore_index=True) # 计算每个年份-月份的降水极值均值 heatmap_data = df_with_month.pivot_table(index='年份', columns='月份', values='降水极值', aggfunc='mean') plt.figure(figsize=(12, 10)) sns.heatmap(heatmap_data, cmap='YlGnBu', annot=False, fmt='.1f') plt.xlabel('月份') plt.ylabel('年份') plt.title('曼尼托巴省各年份-月份降水极值均值热力图') plt.show()
内容的提问来源于stack exchange,提问作者Sparsh Garg
相关产品推荐
相关产品推荐

