如何将datetime.datetime对象转为星期几并绘制分日小时直方图?
解决datetime列表按星期几分组绘制小时直方图的问题
看起来你已经找对了方向——datetime.weekday()方法确实是返回0代表周一、6代表周日的,问题应该出在如何按星期几分组并分别绘制直方图上。我来给你一步步拆解实现方案:
步骤1:准备数据并提取关键字段
首先我们把你的datetime列表转换成更方便处理的DataFrame,同时提取出星期几和小时两个字段:
import datetime import pandas as pd import matplotlib.pyplot as plt # 你的原始数据 x1 = [ datetime.datetime(2019, 8, 18, 21, 21, 23), datetime.datetime(2019, 8, 18, 20, 38, 6), datetime.datetime(2019, 8, 18, 18, 45, 38), datetime.datetime(2019, 8, 18, 15, 35, 25), datetime.datetime(2019, 8, 18, 15, 29, 54), datetime.datetime(2019, 8, 18, 15, 26, 19) ] # 转换成DataFrame df = pd.DataFrame({'datetime': x1}) # 提取星期几(0=周一,6=周日) df['weekday'] = df['datetime'].apply(lambda dt: dt.weekday()) # 提取小时(直接用dt.hour更简洁) df['hour'] = df['datetime'].dt.hour
步骤2:按星期几分组并绘制直方图
接下来我们创建7个子图(对应一周7天),遍历每个星期几筛选数据并绘制直方图:
# 创建2行4列的子图布局,预留一个位置避免排版拥挤 fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(16, 8)) axes = axes.flatten() # 将二维子图数组转为一维,方便循环遍历 # 星期几的中文标签,对应0-6的数值 weekday_labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] for i in range(7): # 筛选当前星期几的小时数据 weekday_hours = df[df['weekday'] == i]['hour'] # 绘制直方图,设置24个 bins 对应0-23点,添加黑色边框区分柱子 axes[i].hist(weekday_hours, bins=24, range=(0, 24), edgecolor='black') # 设置子图标题 axes[i].set_title(f'{weekday_labels[i]}') # 设置x轴标签 axes[i].set_xlabel('小时') # 设置x轴刻度,每4小时显示一个 axes[i].set_xticks(range(0, 24, 4)) # 隐藏第8个多余的子图 axes[7].axis('off') # 自动调整子图间距,避免标题和标签重叠 plt.tight_layout() plt.show()
备注:你的示例数据里所有datetime都是2019年8月18日(周日,对应weekday=6),所以运行代码后只有周日的子图会有直方图,其他子图是空的。你可以加入其他日期的数据来测试完整效果。
为什么之前用weekday()没达到预期?
如果之前尝试weekday()但没成功,大概率是这几个原因:
- 没有把星期几和小时数据正确对应分组,导致绘图时数据混在一起
- 手动处理分组时逻辑出错,比如遍历星期几的时候没有精准筛选对应的数据
- 没有为每个星期几单独创建子图,而是把所有数据画在了同一个图里
用pandas的结构化数据处理+matplotlib的子图功能,能很清晰地解决这个问题,代码也更容易维护和扩展。
内容的提问来源于stack exchange,提问作者Taco22
相关产品推荐
相关产品推荐

