如何按指定时间单位绘制计数频率直方图?
时间分组频率直方图绘制问题及解决方案
问题背景
我有一份大型数据集,已通过以下代码完成时间分组:
df.groupby(pd.cut(time, np.arange(0, max(time), t))).sum()
其中df为pandas DataFrame,time列是间隔0.00001秒的时间戳数据,t为分组时间单位(例如0.00005秒)。数据集包含countnum(行号)、time(时间戳)、value(数据值)列。但无法绘制出X轴为时间分组、Y轴为频率的直方图,尝试多种方法均未得到正确结果。
示例数据
Count # Time (s) Values (V) 0 1 0.00001 3.022 1 2 0.00002 3.018 2 3 0.00003 3.013 3 4 0.00004 3.003 4 5 0.00005 3.003 5 6 0.00006 3.013 6 7 0.00007 3.013 7 8 0.00008 3.013 8 9 0.00009 3.003 9 10 0.00010 2.998
期望图表样式(假设time=0.00007处另有一个数据)
x x x x x x x x x 0----0.00002-----0.00004-----0.00006-----0.00008
解决方案
1. 修正分组统计逻辑
之前用sum()是对value列求和,要统计每组的频率(样本数量),需改用size():
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 定义分组间隔 t = 0.00005 # 生成包含所有时间的分组区间,末尾加t避免遗漏最大时间 bins = np.arange(0, df['Time (s)'].max() + t, t) # 按区间分组并统计每组行数(频率) grouped_df = df.groupby(pd.cut(df['Time (s)'], bins)).size().reset_index(name='Frequency')
2. 处理X轴标签
pd.cut生成的区间标签可以提取中点作为X轴的代表值,让图表更直观:
# 计算每个时间区间的中点 grouped_df['Time_Mid'] = grouped_df['Time (s)'].apply(lambda interval: (interval.left + interval.right) / 2)
3. 绘制频率直方图
用matplotlib绘制柱状图,对应期望的样式:
plt.figure(figsize=(8, 5)) # 绘制柱状图,宽度设为分组间隔的0.8,避免重叠 plt.bar(grouped_df['Time_Mid'], grouped_df['Frequency'], width=t*0.8, color='b') # 设置X轴刻度和标签 plt.xticks(grouped_df['Time_Mid'], [f'{mid:.5f}' for mid in grouped_df['Time_Mid']], rotation=30) plt.xlabel('时间分组(秒)') plt.ylabel('频率') plt.title('时间分组频率分布') # 调整布局防止标签截断 plt.tight_layout() plt.show()
关键注意点
- 频率统计用
size()而非sum():sum()是对数值列求和,size()才是统计每组的样本数量 - 生成
bins时需在最大值后加t:确保最大时间被包含在最后一个分组区间内 - 用区间中点作为X轴:比左边界更能代表分组的时间位置,图表展示更合理
内容的提问来源于stack exchange,提问作者Celina Emma
相关产品推荐
相关产品推荐

