如何在Matplotlib中基于时间-数值对应列表设置直方图分箱
解决方法
核心思路
先把list1的datetime数据按zip1的时间区间分组统计数量,再用zip2的数值作为分箱绘制直方图。之前的错误大多是因为操作不可变类型(比如float)、参数格式不对导致的。
具体代码实现
先导入依赖库:
import pandas as pd import matplotlib.pyplot as plt from datetime import datetime
1. 数据准备(替换成你的真实数据)
# 示例:zip1是有序时间点,用于划分时间区间;zip2对应每个区间的分箱值 zip1 = [datetime(2023,1,1), datetime(2023,2,1), datetime(2023,3,1), datetime(2023,4,1)] zip2 = [1.0, 2.0, 3.0] # 区间数量=zip1长度-1,所以zip2长度要匹配 list1 = [ datetime(2023,1,15), datetime(2023,1,20), datetime(2023,2,5), datetime(2023,2,10), datetime(2023,2,15), datetime(2023,3,5) ]
2. 分组统计数量
# 先确保zip1是递增排序的(必须,否则区间逻辑混乱) zip1_sorted = sorted(zip1) # 用pandas划分时间区间并统计每个区间的元素数量 # include_lowest=True 让第一个区间包含最左的时间点 count_series = pd.cut( pd.Series(list1), bins=zip1_sorted, labels=zip2, include_lowest=True ).value_counts().sort_index()
3. 绘制直方图
两种方式可选:
方式一:用条形图(更直观,对应离散分箱)
plt.bar(count_series.index, count_series.values, edgecolor='black') plt.xlabel('Zip2 分箱值') plt.ylabel('区间内元素数量') plt.title('时间区间分组频率直方图') plt.show()
方式二:用plt.hist(严格匹配直方图需求)
plt.hist(zip2, bins=len(zip2), weights=count_series.values, edgecolor='black') plt.xlabel('Zip2 分箱值') plt.ylabel('区间内元素数量') plt.show()
错误原因解释
- AttributeError:你之前尝试给
zip2里的float元素添加数据(比如zip2[i].append(xxx)),但float是不可变类型,没有append方法,自然报错。正确做法是新建列表存统计结果,不要修改zip2的元素。 - plt.hist报错:大概率是传入的参数格式不对——比如直接传入混合了datetime的列表,或者
bins参数不是有序的数值数组。用上面的方法把统计后的数量和zip2对应好,再传入就不会出错。
注意事项
- 必须保证
zip1是递增排序的datetime列表,否则区间划分完全混乱。 - 检查长度匹配:
zip2的长度必须等于zip1长度减1(n个时间点划分n-1个区间),否则会出现索引错误或统计结果不匹配。 - 如果
list1有超出zip1区间的元素,pd.cut会默认归为NaN,可通过dropna=False保留,或者调整right/include_lowest参数修改区间开闭规则。
内容的提问来源于stack exchange,提问作者A Z
相关产品推荐
相关产品推荐

