Python列表数据按区间分组统计各组个数

本文介绍了如何使用Python的itertools.groupby函数对列表数据进行分组,并统计每个区间的数量。通过示例展示了如何对分数列表按照一定步长进行分组,输出每个分数段及其出现的次数,例如1.0-3.0区间有2个数,5.0-7.0区间有1个数等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述

今天遇到一个问题,就是有一个列表数据,划分一个固定区间,统计每个区间数量。

解决方案

使用 groupby() 函数

from itertools import groupby

score_list = [6.3, 1.2, 6.2, 5.6, 9.5, 1.6]
step = 1
for k, g in groupby(sorted(score_list), key=lambda x: x//step):
    print('{}-{}: {}'.format(k*step, (k+1)*step+1, len(list(g))))

分组效果

1.0-3.0: 2
5.0-7.0: 1
6.0-8.0: 2
9.0-11.0: 1

<think>嗯,用户需要一段Python代码,用pandas DataFrame批量画直方图,还要多线程,分组处理,筛选数据范围,显示统计指标。首先得理清需求。 首先,用户希望选择一个分组字段和一个待画图的字段,每个分组生成对应的直方图。多线程可能用来加速处理,但得考虑Python的GIL问题,可能用concurrent.futures的ThreadPoolExecutor。不过绘图部分可能受限于matplotlib的backend,多线程是否有效?可能需要测试,但按用户要求尽量实现。 然后是数据筛选,只统计每个分组中值大小排序后5%-95%区间数据。应该用分位数剪裁,比如用quantile()方法,然后过滤掉范围外的数据。注意每个分组单独处理,不能全局剪裁,否则可能影响各组分布。 统计指标方面,每个直方图需要显示均值、中位数、标准差。可以用ax.text在图上添加文本,位置要调整好,别遮挡重要部分。 代码结构方面,可能先定义绘图函数,处理单个分组数据,进行剪裁,画图,添加统计信息。然后用多线程调用这个函数,遍历所有分组。 参数设计:函数需要dataframe,group_col(分组字段),plot_col(画图字段),输出路径,bins数量,是否显示等。主函数里读取数据,获取唯一分组值,分配线程任务。 需要注意matplotlib多线程的问题,可能每个线程生成独立的figure和ax,避免冲突。此外,保存图像时文件名要唯一,可以用分组名,但需要处理特殊字符。 测试的时候,要确保剪裁正确,每个分组单独处理。统计指标计算是否正确,是否在图上显示。多线程是否真的提升速度,尤其是分组很多的时候。 可能的错误点:分组名中有非法字符导致保存失败,分位数计算错误,多线程竞争资源导致图像错乱,或者程序崩溃。需要异常处理,比如try-except块,或者同步机制,但可能复杂。 另外,用户可能希望直方图的bins一致,方便比较,所以可能需要统一bins范围,或者每个分组自动调整。这里按用户需求,可能每个分组独立设置bins。 最后,整理代码结构,添加必要的注释,方便用户理解和使用。可能需要示例数据测试,比如用pd.DataFrame生成虚拟数据分组测试。</think>我为您设计了一个分步实现的Python代码方案。以下是实现思路和完整代码: 1. **核心功能分解** - 使用`ThreadPoolExecutor`实现多线程绘图 - 动态数据过滤:每组数据保留5%-95%分位数范围 - 自动标注关键统计指标 - 分组保存图片文件 ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from concurrent.futures import ThreadPoolExecutor import os def plot_histogram(group_data, group_name, plot_col, output_dir='histograms', bins=30): """ 单个分组的直方图绘制函数 """ try: # 计算分位数边界 lower = group_data[plot_col].quantile(0.05) upper = group_data[plot_col].quantile(0.95) # 过滤数据 filtered_data = group_data[(group_data[plot_col] >= lower) & (group_data[plot_col] <= upper)] if filtered_data.empty: print(f"分组 {group_name} 无有效数据") return # 创建画布 fig, ax = plt.subplots(figsize=(10, 6)) # 绘制直方图 ax.hist(filtered_data[plot_col], bins=bins, edgecolor='black', alpha=0.7) # 计算统计指标 mean = filtered_data[plot_col].mean() median = filtered_data[plot_col].median() std = filtered_data[plot_col].std() # 添加标注 textstr = '\n'.join(( f'均值: {mean:.2f}', f'中位数: {median:.2f}', f'标准差: {std:.2f}')) ax.text(0.75, 0.95, textstr, transform=ax.transAxes, verticalalignment='top', bbox=dict(boxstyle='round', alpha=0.5)) # 设置标题 ax.set_title(f'{plot_col} 分布 - 分组: {group_name}\n(显示5%-95%分位数数据)') ax.set_xlabel(plot_col) ax.set_ylabel('频数') # 保存图片 os.makedirs(output_dir, exist_ok=True) safe_name = str(group_name).replace("/", "_").replace("\\", "_") # 处理特殊字符 plt.savefig(f'{output_dir}/{plot_col}_{safe_name}.png') plt.close() except Exception as e: print(f"分组 {group_name} 绘图失败: {str(e)}") def batch_histogram(df, group_col, plot_col, max_workers=4): """ 批量直方图生成主函数 """ groups = df[group_col].unique() with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [] for group in groups: group_data = df[df[group_col] == group] futures.append( executor.submit( plot_histogram, group_data=group_data, group_name=group, plot_col=plot_col ) ) # 等待所有任务完成 for future in futures: future.result() # 使用示例 if __name__ == "__main__": # 生成测试数据 data = { 'group': np.random.choice(['A', 'B', 'C'], 1000), 'value': np.concatenate([ np.random.normal(50, 10, 700), np.random.normal(150, 50, 300) ]) } df = pd.DataFrame(data) # 执行批处理 batch_histogram(df=df, group_col='group', plot_col='value', max_workers=3) ``` **代码特点说明:** 1. **数据预处理** - 自动计算每个分组的5%和95%分位数 - 过滤极端值前会检查空数据集 - 使用`str(group_name).replace()`处理特殊字符,避免文件保存失败 2. **可视化优化** - 自动调整图形尺寸(`figsize=(10,6)`) - 添加半透明边框(`edgecolor='black', alpha=0.7`) - 统计信息使用半透明圆角文本框展示 3. **多线程实现** - 使用`ThreadPoolExecutor`控制最大线程数 - 每个分组独立线程处理 - 自动等待所有任务完成 4. **异常处理** - 使用try-except捕获单个分组的绘图错误 - 空数据集时跳过处理 **使用建议:** 1. 调整`max_workers`参数根据CPU核心数设置 2. 输出目录默认在当前路径下的`histograms`文件夹 3. 可通过修改`plot_histogram`函数的`bins`参数调整直方图分箱数 4. 统计指标保留两位小数,可根据需要修改格式字符串 **效果示例:** 生成的直方图会包含: - 过滤后的数据分布 - 醒目的统计指标标注 - 自动命名的分组标题 - 统一规范的坐标轴标签 该实现方案在保持代码简洁性的同时,兼顾了执行效率和异常处理,适合处理中等规模的数据集(10万行级别数据)。对于超大数据集建议增加内存检查机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

detayun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值