如何在Pandas中对DataFrame各列数值进行分箱并统计区间频数
问题描述
现有如下DataFrame:
| columns1 | parametr_1 | parametr_2 | parametr_3 |
|---|---|---|---|
| val_1 | 1 | 2 | 1 |
| val_2 | 1 | 2 | 5 |
| val_3 | 7 | 1 | 7 |
| val_4 | 4 | 2 | 11 |
需求:
- 将每个参数列(
parametr_1、parametr_2、parametr_3)划分为指定区间,得到如下格式的统计结果:
| column | bin | count |
|---|---|---|
| parametr_1 | (0-1) | 2 |
| parametr_1 | (1-inf) | 2 |
| parametr_2 | (0-2) | 3 |
| parametr_2 | (2-inf) | 0 |
| parametr_3 | (0-5) | 2 |
| parametr_3 | (5-inf) | 2 |
- 将同一参数对应的
column列单元格进行合并,最终结果仅显示单个parametr_1、parametr_2、parametr_3单元格。
请问是否有专门的库可以实现该需求?
解决方案
当然有!Pandas就是处理这类表格数据的绝佳工具,结合它的样式功能或者Excel处理库,就能完美实现你的需求。下面分步骤说明:
1. 生成区间统计结果
首先用Pandas的cut()函数划分区间,再通过分组统计得到计数(包括区间内为0的情况):
import pandas as pd import numpy as np # 构造原始DataFrame df = pd.DataFrame({ 'columns1': ['val_1', 'val_2', 'val_3', 'val_4'], 'parametr_1': [1, 1, 7, 4], 'parametr_2': [2, 2, 1, 2], 'parametr_3': [1, 5, 7, 11] }) # 定义每个参数的区间规则 bin_rules = { 'parametr_1': [0, 1, np.inf], 'parametr_2': [0, 2, np.inf], 'parametr_3': [0, 5, np.inf] } # 生成对应格式的区间标签 bin_labels = { 'parametr_1': ['(0-1)', '(1-inf)'], 'parametr_2': ['(0-2)', '(2-inf)'], 'parametr_3': ['(0-5)', '(5-inf)'] } # 遍历每个参数列生成统计结果 result_list = [] for col in bin_rules.keys(): # 划分区间 bins = pd.cut(df[col], bins=bin_rules[col], labels=bin_labels[col], include_lowest=True) # 统计每个区间数量,补充缺失区间的0计数 count_df = bins.value_counts().reindex(bin_labels[col], fill_value=0).reset_index() count_df.columns = ['bin', 'count'] count_df['column'] = col result_list.append(count_df) # 合并所有结果 final_result = pd.concat(result_list, ignore_index=True)[['column', 'bin', 'count']] print(final_result)
运行后会得到和需求完全匹配的统计数据:
column bin count 0 parametr_1 (0-1) 2 1 parametr_1 (1-inf) 2 2 parametr_2 (0-2) 3 3 parametr_2 (2-inf) 0 4 parametr_3 (0-5) 2 5 parametr_3 (5-inf) 2
2. 合并同一参数的单元格
如果要在可视化输出(比如Jupyter Notebook)或Excel中实现单元格合并,有两种常用方式:
方式一:Jupyter中用Pandas样式合并
利用Pandas的Styler对象设置合并规则,在Notebook中直接展示合并效果:
def merge_cells(df): # 找出需要合并的行索引范围 merge_indices = [] current_col = df.iloc[0]['column'] start_idx = 0 for idx in range(1, len(df)): if df.iloc[idx]['column'] != current_col: merge_indices.append((start_idx, idx-1)) current_col = df.iloc[idx]['column'] start_idx = idx merge_indices.append((start_idx, len(df)-1)) # 定义合并样式 styles = [] for start, end in merge_indices: # 设置合并单元格的样式 styles.append({ 'selector': f'tbody tr:nth-child({start+1}) td:first-child', 'props': [('vertical-align', 'middle'), ('text-align', 'center'), ('border', '1px solid #ccc')] }) styles.append({ 'selector': f'tbody tr:nth-child({start+1}) td:first-child', 'props': [('rowspan', f'{end - start + 1}')] }) # 隐藏被合并的单元格 for i in range(start+1, end+1): styles.append({ 'selector': f'tbody tr:nth-child({i+1}) td:first-child', 'props': [('display', 'none')] }) # 应用样式到DataFrame styled_df = df.style.set_table_styles(styles).set_properties(**{'border': '1px solid #ccc'}) return styled_df # 展示带合并单元格的表格 merge_cells(final_result)
方式二:导出到Excel时合并单元格
如果需要导出到Excel并保留合并格式,搭配openpyxl库实现:
from openpyxl import load_workbook from openpyxl.styles import Alignment # 先导出统计结果到Excel final_result.to_excel('param_stats.xlsx', index=False) # 加载工作簿处理合并 wb = load_workbook('param_stats.xlsx') ws = wb.active # 合并相同参数的单元格 current_col = ws['A2'].value start_row = 2 for row in range(3, ws.max_row+1): if ws[f'A{row}'].value != current_col: ws.merge_cells(f'A{start_row}:A{row-1}') # 设置垂直居中对齐 ws[f'A{start_row}'].alignment = Alignment(vertical='center', horizontal='center') current_col = ws[f'A{row}'].value start_row = row # 合并最后一组单元格 ws.merge_cells(f'A{start_row}:A{ws.max_row}') ws[f'A{start_row}'].alignment = Alignment(vertical='center', horizontal='center') # 保存文件 wb.save('param_stats_merged.xlsx')
导出的Excel文件中,column列的相同参数单元格会自动合并,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Archi
相关产品推荐
相关产品推荐

