问题描述
我有一个我重复的过程......经常,但不知道如何创建一个动态函数来使这更容易。我需要取一个变量(例如年龄)并将年龄分箱到至少等于另一列(重量)1000 个单位的离散箱中。我需要对任何变量动态执行此操作并控制权重总和。因此,如果我想以 500 个单位或 2000 个单位为增量进行分类,我需要将其作为可变参数。
这是一个示例数据集:
import pandas as pd
import numpy as np
age = np.arange(0,30,1)
weight = np.linspace(200,2500,30)
bin_dict = {'age':age,'weight':weight}
df = pd.DataFrame(bin_dict)
现在假设我想将 bin 年龄划分为不少于 1000 个单位的 bin。这就是结果的样子:
df['bin_aged'] = pd.cut(df['age'],bins = [-np.inf,3,5,7,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,np.inf],labels = [3,29])
如果我按新的分箱列分组,它会是什么样子:
df.groupby('bin_aged').agg({'weight':'sum'})
这可能吗?
解决方法
我想通了....
def dynamic_bin(df,column,weight,minimum):
"""
Parameters
----------
df : dataframe
column : column to be binned
weight : column that will dictate the bin
minimum : minimum weight per bin
Returns
-------
df : dataframe with new binned column
"""
bins = [-np.inf]
labels = []
hold_over = []
for i in sorted(df[column].unique()):
g = df[df[column] == i].groupby(column).agg({weight:'sum'}).reset_index()
if g[weight].values[0] < minimum:
if hold_over is None:
hold_over.append(g[weight].values[0])
elif (sum(hold_over) + g[weight].values[0]) < minimum:
hold_over.append(g[weight].values[0])
elif (sum(hold_over) + g[weight].values[0]) >= minimum:
hold_over.clear()
bins.append(g[column].values[0])
labels.append(g[column].values[0])
elif g[weight].values[0] >= minimum:
bins.append(g[column].values[0])
labels.append(g[column].values[0])
bins.pop()
bins.append(np.inf)
str_column = str(column)+str("_binned")
# print(str_column)
df[str_column] = pd.cut(df[column],bins = bins,labels = labels)
return df