使用带有间隔描述的表在python中编码DataFrame中的值

时间:2018-07-11 11:19:16

标签: python pandas binning

我在熊猫df1中有一张桌子

id   value
1    1500
2    -1000
3    0   
4    50000  
5    50   

我在数据帧df2中还有另一个表,该表包含组的上限,因此基本上每一行都代表从前一个边界到当前边界的间隔(第一个间隔是“ <0”):

group   upper
0       0
1       1000
2       NaN

我应该如何使用df2中的间隔从df中获得价值的相关组?我不能使用连接,合并等,因为此连接的规则应类似于“如果值在先前的上限和当前上限之间”,而不是“如果值等于某值”。我发现的唯一方法是将预定义函数与df.apply()一起使用(在其中也存在带有interval_flag == False的分类值的情况):

def values_to_group(x, interval_flag, groups_def):
    if interval_flag==True:
        for ind, gr in groups_def.sort_values(by='group').iterrows():
            if x<gr[1]:
                return gr[0]
            elif math.isnan(gr[1]) == True:
                return gr[0]
    else:
        for ind, gr in groups_def.sort_values(by='group').iterrows():
            if x in gr[1]:
                return gr[0]

有没有更简单/更优化的方法?

预期输出应为:

id   value   group
1    1500    2
2    -1000   0
3    0       1
4    50000   2
5    50      1

2 个答案:

答案 0 :(得分:0)

我建议将DataFrame中的df2中的upperNaN一起使用,并将最后的np.inf替换为df2 = pd.DataFrame({'group':[0,1,2], 'upper':[0,1000,np.nan]}) df2 = df2.sort_values('upper') df2['upper'] = df2['upper'].replace(np.nan, np.inf) print (df2) group upper 0 0 0.000000 1 1 1000.000000 2 2 inf #added first bin -np.inf bins = np.insert(df2['upper'].values, 0, -np.inf) df1['group'] = pd.cut(df1['value'], bins=bins, labels=df2['group'], right=False) print (df1) id value group 0 1 1500 2 1 2 -1000 0 2 3 0 1 3 4 50000 2 4 5 50 1

#pricing

答案 1 :(得分:0)

这是使用numpy.digitize的解决方案。您唯一的任务是构造binsnames输入列表,这应该可以通过输入数据框实现。

import pandas as pd, numpy as np

df = pd.DataFrame({'val': [99, 53, 71, 84, 84]})
df['ratio'] = df['val']/ df['val'].shift() - 1

bins = [-np.inf, 0, 0.2, 0.4, 0.6, 0.8, 1.0, np.inf]
names = ['<0', '0.0-0.2', '0.2-0.4', '0.4-0.6', '0.6-0.8', '0.8-1.0', '>1']

d = dict(enumerate(names, 1))

df['Bucket'] = list(map(d.get, np.digitize(df['ratio'], bins)))

print(df)

   val     ratio   Bucket
0   99       NaN     None
1   53 -0.464646       <0
2   71  0.339623  0.2-0.4
3   84  0.183099  0.0-0.2
4   84  0.000000  0.0-0.2