Python绘制月度归一化压力直方图及代码报错解决求助
问题:基于CSV压力数据绘制月度归一化直方图并导出PDF
我有一份格式如下的CSV数据:
Time Pressure 1/1/2017 0:00 5.8253 ... ... 3/1/2017 0:10 4.2785 4/1/2017 0:20 5.20041 5/1/2017 0:30 4.40774 6/1/2017 0:40 4.03228 7/1/2017 0:50 5.011924 12/1/2017 1:00 3.9309888
我想要基于这些压力数据绘制月度归一化直方图,最终把图表写入PDF文件。我知道需要用到Groupby和numpy.hist功能,但作为Python新手,不确定怎么正确使用。下面是我尝试的两段代码及对应的报错:
尝试的代码1
n = len(df) // 5 for tmp_df in (df[i:i+n] for i in range(0, len(df), n)): gb_tmp = tmp_df.groupby(pd.Grouper(freq='M')) ax = gb_tmp.hist() plt.setp(ax.xaxis.get_ticklabels(),rotation=90) plt.show() plt.close()
报错信息
ValueError: range() 参数3不能为0
尝试的代码2
df1 = df.groupby(pd.Grouper(freq='M')) np.histogram(df1,bins=10,range=None,normed=True)
报错信息
ValueError: DataFrame的真值不明确,请使用a.empty、a.bool()、a.item()、a.any()或a.all()
我尝试了上述代码但都出现错误,不确定用法是否正确,恳请帮助!
解决方案
首先,咱们先梳理下你的问题根源,再一步步解决:
第一步:先确保数据格式正确
从你给出的CSV内容来看,数据是Time Pressure后跟成对的时间和压力值,这说明你需要先把数据整理成**两列(时间、压力)**的标准DataFrame,不然后续的分组和绘图都会出问题。可以这样处理:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages # 读取并整理数据 # 假设你的CSV文件名为pressure_data.csv with open('pressure_data.csv', 'r') as f: data = f.read().split() # 跳过前两个表头,成对提取时间和压力值 time_values = data[2::2] pressure_values = data[3::2] # 转换为DataFrame,将时间列转为datetime类型并设为索引 df = pd.DataFrame({ 'Time': pd.to_datetime(time_values, format='%d/%m/%Y %H:%M'), 'Pressure': pd.to_numeric(pressure_values) }).set_index('Time')
第二步:解决代码1的错误
你代码里的n = len(df) //5,如果数据行数小于5,n会变成0,导致range(0, len(df), 0)触发报错。其实完全不需要拆分DataFrame,直接按月份分组即可。
第三步:正确实现月度归一化直方图并导出PDF
我们可以按月份分组后,对每个月的压力数据计算归一化直方图,然后把所有子图统一写入PDF:
# 按自然月份分组 month_groups = df.groupby(pd.Grouper(freq='M')) # 创建PDF对象,用于保存所有图表 with PdfPages('monthly_normalized_histograms.pdf') as pdf: # 遍历每个月份的数据组 for month, group in month_groups: if group.empty: continue # 跳过没有数据的月份 # 计算归一化直方图(density=True表示归一化为概率密度,面积总和为1) counts, bins = np.histogram(group['Pressure'], bins=10, density=True) # 绘制直方图 plt.figure(figsize=(8, 5)) plt.hist(bins[:-1], bins, weights=counts, edgecolor='black') plt.title(f'Normalized Pressure Histogram - {month.strftime("%Y-%m")}') plt.xlabel('Pressure') plt.ylabel('Normalized Frequency') plt.grid(axis='y', alpha=0.3) # 将当前图表添加到PDF pdf.savefig() plt.close()
关键步骤解释
- 数据整理:把原始扁平化的CSV数据转换成标准结构,将时间转为datetime类型并设为索引,这是按月份分组的基础。
- 分组逻辑:
pd.Grouper(freq='M')会自动按自然月份分组,无需手动处理不同月份的天数差异。 - 归一化直方图:
np.histogram的density=True参数会将直方图归一化为概率密度,确保不同月份的直方图可以横向对比。 - PDF导出:使用
PdfPages可以将多个图表依次写入同一个PDF文件,避免手动保存多张图片再合并的麻烦。
代码2报错原因
df.groupby(pd.Grouper(freq='M'))返回的是GroupBy对象,不是直接的数值数组,而np.histogram需要一维数值数据作为输入,所以必须遍历分组,取出每个组的压力数据后再计算直方图。
内容的提问来源于stack exchange,提问作者Unknown
相关产品推荐
相关产品推荐

