基于OBIS与Value列自动生成自定义分类数的Classification列函数需求
自动按OBIS分组实现等距分箱生成Classification列
需求背景
现有Pandas DataFrame df,需基于OBIS编号与Value列生成Classification列。当前通过手动编写条件列表与对应值的方式实现,每次调整分类数量(如示例中的5类,最多支持10类)时,需重新计算各OBIS分组下的分位数阈值,操作繁琐。现有12个OBIS编号,希望实现一个可自定义分类数的函数,自动按OBIS分组完成等距分箱分类,替代现有重复代码。
原手动实现代码:
import numpy as np import pandas as pd # 原手动条件与值列表 conditions = [ (df['OBIS'] == '1.8.0') & (df['Value'] < 39469.79), (df['OBIS'] == '1.8.0') & (df['Value'] >= 39469.79) & (df['Value'] < 78939.58), (df['OBIS'] == '1.8.0') & (df['Value'] >= 78939.58) & (df['Value'] < 118409.37), (df['OBIS'] == '1.8.0') & (df['Value'] >= 118409.37) & (df['Value'] < 157879.16), (df['OBIS'] == '1.8.0') & (df['Value'] >= 157879.16), (df['OBIS'] == '1.9.0') & (df['Value'] < 1.41), (df['OBIS'] == '1.9.0') & (df['Value'] >= 1.41) & (df['Value'] < 2.82), (df['OBIS'] == '1.9.0') & (df['Value'] >= 2.82) & (df['Value'] < 4.22), (df['OBIS'] == '1.9.0') & (df['Value'] >= 4.22) & (df['Value'] < 5.63), (df['OBIS'] == '1.9.0') & (df['Value'] >= 5.63), (df['OBIS'] == '2.8.0') & (df['Value'] < 0.008), (df['OBIS'] == '2.8.0') & (df['Value'] >= 0.008) & (df['Value'] < 0.016), (df['OBIS'] == '2.8.0') & (df['Value'] >= 0.016) & (df['Value'] < 0.024), (df['OBIS'] == '2.8.0') & (df['Value'] >= 0.024) & (df['Value'] < 0.032), (df['OBIS'] == '2.8.0') & (df['Value'] >= 0.032) ] values = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4] df["Classification"] = np.select(conditions, values)
解决方案
利用Pandas的groupby+cut函数实现分组等距分箱,无需手动计算阈值,分类数可灵活调整:
自定义函数实现
import pandas as pd def add_grouped_equal_width_class(df, obis_col='OBIS', value_col='Value', class_num=5, new_col='Classification'): """ 按OBIS分组,对Value列做等距分箱,生成Classification列 参数: df: 目标DataFrame obis_col: OBIS编号列名,默认'OBIS' value_col: 用于分箱的数值列名,默认'Value' class_num: 分类数量,默认5 new_col: 生成的分类列名,默认'Classification' 返回: 添加了分类列的DataFrame """ # 按OBIS分组,对每个组的Value列应用等距分箱 df[new_col] = df.groupby(obis_col)[value_col].transform( lambda x: pd.cut(x, bins=class_num, labels=False, include_lowest=True) ) return df
使用示例
# 生成分类列,设置分类数为5 df = add_grouped_equal_width_class(df, class_num=5) # 如果需要调整分类数,直接修改参数即可,比如改为3类 df = add_grouped_equal_width_class(df, class_num=3)
说明
pd.cut的bins=class_num指定等距分箱的数量,自动计算每个OBIS分组的阈值labels=False返回箱的索引(从0开始),与原手动实现的分类编号逻辑一致include_lowest=True确保最小值被包含在第一个分箱中,避免边界值遗漏- 支持任意数量的OBIS分组,无需修改函数逻辑
内容的提问来源于stack exchange,提问作者Assetto
相关产品推荐
相关产品推荐

