使用Python Pandas根据第二个数据框定义的区间对第一个数据框的数据进行分箱

3 投票
2 回答
1590 浏览
提问于 2025-04-19 16:09

我正在尝试根据第二个数据表中定义的区间,把一个数据表中的数据分组。我在想,可能可以用pd.bin和pd.merge的组合来实现这个目标?

这就是每个数据表目前的样子:

df = pd.DataFrame({'id':['a', 'b', 'c', 'd','e'],
                   'bin':[1, 2, 3, 3, 2],
                   'perc':[0.1,0.9,0.3,0.7,0.5]})

df2 = pd.DataFrame({'bin':[1, 1, 1, 2, 2, 2, 3, 3, 3], 
                    'result':['low', 'medium','high','low', 'medium','high','low', 'medium','high'],
                    'cut_min':[0,0.2,0.6,0,0.3,0.7,0,0.4,0.8],
                    'cut_max':[0.2,0.6,1,0.3,0.7,1,0.4,0.8,1]})

第一个数据表(df):

bin id  perc
1   a   0.1
2   b   0.9
3   c   0.3
3   d   0.7
2   e   0.5

这是包含区间的表,第二个数据表(df2):

bin cut_max cut_min result
1   0.2     0.0     low
1   0.6     0.2     medium
1   1.0     0.6     high
2   0.3     0.0     low
2   0.7     0.3     medium
2   1.0     0.7     high
3   0.4     0.0     low
3   0.8     0.4     medium
3   1.0     0.8     high

我想要根据区间,把第一个数据表中的值与第二个数据表中的合适结果匹配,具体是用cut_min和cut_max来包含第一个数据表中的perc值。所以,我希望最终的表格看起来像这样:

bin id  perc    result
1   a   0.1     low
2   b   0.9     high
3   c   0.3     low
3   d   0.7     medium
2   e   0.5     medium

我最开始是用SQL查询来写这个,简单地通过连接就完成了这个任务:

select
  df.id
  , df.bin
  , df.perc
  , df2.result
from df
inner join df2
  on df.bin = df2.bin
  and df.perc >= df2.cut_min 
  and df.perc < df2.cut_max

如果有人知道用Pandas实现这个的好方法,我会非常感激!(其实这是我第一次在stackoverflow上找不到解决方案,所以如果上面的内容解释得不够清楚,我先说声抱歉!)

2 个回答

0

模块 bitstring 里面有一个叫做 BitArray 的类,你可以用一个字节数组来初始化它:

(你需要先用 pip install bitarray 来安装这个模块)

from bitstring import BitArray


BitArray(bytes = <byte_array>)
5

首先,dfdf2 这两个数据框根据 bin 这一列合并,然后再选择那些满足条件的行,条件是 cut_min <= perc < cut_max

In [95]: result = pd.merge(df, df2, on='bin').query('cut_min <= perc < cut_max'); result
Out[95]: 
    bin id  perc  cut_max  cut_min  result
0     1  a   0.1      0.2      0.0     low
5     2  b   0.9      1.0      0.7    high
7     2  e   0.5      0.7      0.3  medium
9     3  c   0.3      0.4      0.0     low
13    3  d   0.7      0.8      0.4  medium

In [97]: result = result[['bin', 'id', 'perc', 'result']]

In [98]: result.sort('id')
Out[98]: 
    bin id  perc  result
0     1  a   0.1     low
5     2  b   0.9    high
9     3  c   0.3     low
13    3  d   0.7  medium
7     2  e   0.5  medium

撰写回答