如何利用Pandas DataFrame绘制指定地点12个月就诊数折线图
解决方案与优化建议
一、核心实现步骤
1. 日期字段预处理
先把date of visit转为datetime类型,再筛选出目标地点的近12个月数据:
import pandas as pd # 转换日期列格式 df['date of visit'] = pd.to_datetime(df['date of visit']) # 定义目标地点和时间范围 target_location = '目标诊所名称' latest_date = df['date of visit'].max() start_date = latest_date - pd.DateOffset(months=12) # 筛选数据 filtered_data = df[(df['location'] == target_location) & (df['date of visit'] >= start_date) & (df['date of visit'] <= latest_date)]
2. 统计每月就诊数
直接对筛选后的数据按月份分组统计,避免拆分多个数据集的冗余操作:
# 提取年份+月份(确保跨年时的连续性,格式如'2023-05') filtered_data['month'] = filtered_data['date of visit'].dt.to_period('M') # 统计每月就诊数:如果同一患者当月多次就诊算1次,用nunique;算多次则用size monthly_visit_count = filtered_data.groupby('month')['patient id'].nunique().reset_index(name='visit_num') # 多次就诊统计写法:monthly_visit_count = filtered_data.groupby('month').size().reset_index(name='visit_num')
3. 绘制折线图
用matplotlib生成横轴为月份的折线图:
import matplotlib.pyplot as plt plt.figure(figsize=(10, 6)) plt.plot(monthly_visit_count['month'].astype(str), monthly_visit_count['visit_num'], marker='o', linestyle='-') plt.title(f'{target_location} 12个月就诊数趋势') plt.xlabel('月份') plt.ylabel('就诊数') plt.xticks(rotation=45) plt.tight_layout() plt.show()
二、解决拆分数据集赋值失效的问题
你之前的赋值失效大概率是链式索引引发的SettingWithCopyWarning,Pandas会阻止对切片副本的修改。解决方式:
- 优先选择直接筛选+分组的方式,避免拆分多个数据集
- 若必须拆分,用
.copy()创建独立副本:
# 错误示例(可能导致赋值失败) clinic_data = df[df['location'] == target_location] clinic_data['month'] = clinic_data['date of visit'].dt.to_period('M') # 正确示例 clinic_data = df[df['location'] == target_location].copy() clinic_data['month'] = clinic_data['date of visit'].dt.to_period('M')
三、优化建议
- 处理缺失值:提前清理关键字段的缺失数据,避免统计偏差:
df = df.dropna(subset=['date of visit', 'location', 'patient id']) - 补全空月份:如果某些月份无就诊记录,补充0值防止折线图断层:
# 生成完整的12个月序列 full_month_range = pd.period_range(start=start_date, end=latest_date, freq='M') full_month_df = pd.DataFrame({'month': full_month_range}) # 合并统计数据,空月份填充0 monthly_visit_count = pd.merge(full_month_df, monthly_visit_count, on='month', how='left').fillna(0) - 多地点对比绘图:如需同时展示多个诊所趋势,循环分组即可:
all_locations = df['location'].unique() plt.figure(figsize=(12, 7)) for loc in all_locations: loc_data = df[(df['location'] == loc) & (df['date of visit'] >= start_date)] loc_monthly = loc_data.groupby(loc_data['date of visit'].dt.to_period('M'))['patient id'].nunique() plt.plot(loc_monthly.index.astype(str), loc_monthly.values, marker='o', label=loc) plt.title('各诊所12个月就诊数趋势对比') plt.xlabel('月份') plt.ylabel('就诊数') plt.xticks(rotation=45) plt.legend() plt.tight_layout() plt.show() - 性能优化:大数据集下先按日期范围筛选,再按地点分组,减少计算量。
内容的提问来源于stack exchange,提问作者Liam O'Keefe
相关产品推荐
相关产品推荐

