You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:12:42