具有容差的熊猫 DataFrame.groupby

des*_*cto 5 python numpy pandas

鉴于以下一些数据:

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

df = pd.DataFrame(data)
df
Run Code Online (Sandbox Code Playgroud)

这导致以下数据帧:

Out[6]:
   Length Object
0   10.10   objA
1   10.02   objB
2    7.40   objC
3    6.24   objD
4    5.99   objE
Run Code Online (Sandbox Code Playgroud)

我想根据 +- 容差对“长度”列进行分组。这样做会给我以下组。类似于下面伪代码

tolerance = .25
grouped = df.groupby(df['Length'] +- tolerance)
Run Code Online (Sandbox Code Playgroud)

这将导致类似于以下分组的分组:

{(10.10+-.25): [0L, 1L],
 (7.40+-.25):  [2L],
 (6.24+-.25):  [3L, 4L]}
Run Code Online (Sandbox Code Playgroud)

环顾四周,人们建议使用pd.cut和预定义 bin,然而,鉴于我的数据集的真实大小和长度的可变性,预计算 bin 范围似乎有点暴力解决方案。有没有人有更优雅/快速/熊猫/麻木式的解决方案?

roo*_*oot 2

我建议使用intervaltreePyPI 上的包,而不是 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
Run Code Online (Sandbox Code Playgroud)

字典result如下:

{10.1: ['objA', 'objB'], 5.99: ['objD', 'objE'], 10.02: ['objA', 'objB'], 6.24: ['objD'], 7.4: ['objC']}
Run Code Online (Sandbox Code Playgroud)

它并不完全符合您指定的格式,但它应该足够简单,可以对您需要的格式进行任何更改。