pandas DataFrame.groupby带有容差

6

假设有以下一些数据的位:

data = {'Object': ['objA', 'objB', 'objC', 'objD', 'objE'],
        'Length': [10.1, 10.02, 7.4, 6.24, 5.99]}

df = pd.DataFrame(data)
df

这导致生成以下数据框:
Out[6]:
   Length Object
0   10.10   objA
1   10.02   objB
2    7.40   objC
3    6.24   objD
4    5.99   objE

我想根据+-误差将'Length'列分组。这样做会给我以下分组结果。类似下面的伪代码:
tolerance = .25
grouped = df.groupby(df['Length'] +- tolerance)

这将导致类似下面的分组:
{(10.10+-.25): [0L, 1L],
 (7.40+-.25):  [2L],
 (6.24+-.25):  [3L, 4L]}

看了一些资料,有人建议使用pd.cut和预定义的bins,但是由于我的数据集实际大小和长度变化的可变性,预计算bin范围似乎是一种比较暴力的解决方法。有没有更加优雅/快速/pandas/numpy风格的解决方案呢?


你首先需要分组。否则,你如何区分下一行中的10.10 +/- 0.25和10.02 +/- 0.25? - Alexander
使用pd.cut时,结果是否总是互斥的,即一个值只能存在于binA或binB中,而不能同时存在于binA和binB中? - destructo
我同意@Alexander的观点。为了对数据有一个“感性”的认识,我会将它们绘制成直方图,其中bin的大小是您的测量分辨率(0.01)。这样您就可以快速直观地了解您的实际数据。如果您担心速度问题并且确实有大量数据,我建议将它们放入数据库中,让其他人来解决快速比较的问题。 - roadrunner66
似乎通过pd.cut(或.hist)的分箱方式创建了互斥项。在这种特殊情况下,我需要桶中的重叠部分。然而,这些响应对我需要生成的其他报告非常有用。谢谢! - destructo
1个回答

2
我建议使用PyPI上的intervaltree包,而不是使用类似于pandas/numpy的解决方案。
其思路是将每个长度加上/减去公差后的区间添加到区间树中,并将区间映射到相关联的对象。然后,遍历这些长度并查询区间树。这将给出所有具有包含所查询长度的公差区间的对象。
from intervaltree import IntervalTree

t = IntervalTree()
for length, obj in zip(data['Length'], data['Object']):
    t[length-tolerance:length+tolerance] = obj

result = {}
for length in data['Length']:
    objs = [iv.data for iv in t[length]]
    result[length] = objs

结果字典如下:
{10.1: ['objA', 'objB'], 5.99: ['objD', 'objE'], 10.02: ['objA', 'objB'], 6.24: ['objD'], 7.4: ['objC']}

这不完全符合您指定的格式,但是更改格式应该很容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接