在 pandas Intervalindex中查找匹配间隔 [英] Finding matching interval(s) in pandas Intervalindex

查看:99
本文介绍了在 pandas Intervalindex中查找匹配间隔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

0.20中有一个有趣的API,称为Intervalindex new,可让您创建间隔索引.

There's this interesting API called Intervalindex new in 0.20 that lets you create an index of intervals.

给出一些示例数据:

data = [(893.1516130000001, 903.9187099999999),
 (882.384516, 893.1516130000001),
 (817.781935, 828.549032)]

您可以这样创建索引:

idx = pd.IntervalIndex.from_tuples(data)

print(idx)
IntervalIndex([(893.151613, 903.91871], (882.384516, 893.151613], (817.781935, 828.549032]]
              closed='right',
              dtype='interval[float64]')

Interval s的一个有趣特性是,您可以使用in执行间隔检查:

An interesting property of Intervals is that you can perform interval checks with in:

print(y[-1])
Interval(817.78193499999998, 828.54903200000001, closed='right')

print(820 in y[-1])
True

print(1000 in y[-1])
False

我想知道如何将此操作应用于整个索引.例如,给定某个数字900,如何获取该数字适合的间隔的布尔掩码?

I would like to know how to apply this operation to the entire index. For example, given some number 900, how could I retrieve a boolean mask of intervals for which this number fits in?

我能想到的:

m = [900 in y for y in idx]
print(m)
[True, False, False]

还有更好的方法吗?

推荐答案

如果您对性能感兴趣,可以对IntervalIndex进行优化以进行搜索.使用.get_loc.get_indexer使用内部构建的IntervalTree(如二叉树),该树是在首次使用时构造的.

If you are interested in performance, an IntervalIndex is optimized for searching. using .get_loc or .get_indexer uses an internally built IntervalTree (like a binary tree), which is constructed on first use.

In [29]: idx = pd.IntervalIndex.from_tuples(data*10000)

In [30]: %timeit -n 1 -r 1 idx.map(lambda x: 900 in x)
92.8 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

In [40]: %timeit -n 1 -r 1 idx.map(lambda x: 900 in x)
42.7 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

# construct tree and search
In [31]: %timeit -n 1 -r 1 idx.get_loc(900)
4.55 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

# subsequently
In [32]: %timeit -n 1 -r 1 idx.get_loc(900)
137 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

# for a single indexer you can do even better (note that this is
# dipping into the impl a bit
In [27]: %timeit np.arange(len(idx))[(900 > idx.left) & (900 <= idx.right)]
203 µs ± 1.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

请注意,.get_loc()返回一个索引器(实际上比布尔数组有用,但它们可以相互转换).

Note that .get_loc() returns an indexer (which is actually more useful than a boolean array, but they are convertible to each other).

In [38]: idx.map(lambda x: 900 in x)
    ...: 
Out[38]: 
Index([ True, False, False,  True, False, False,  True, False, False,  True,
       ...
       False,  True, False, False,  True, False, False,  True, False, False], dtype='object', length=30000)

In [39]: idx.get_loc(900)
    ...: 
Out[39]: array([29997,  9987, 10008, ..., 19992, 19989,     0])

返回布尔数组将转换为索引器数组

Returning a boolean array is converted to an array of indexers

In [5]: np.arange(len(idx))[idx.map(lambda x: 900 in x).values.astype(bool)]
Out[5]: array([    0,     3,     6, ..., 29991, 29994, 29997])

.get_loc()和.get_indexer()返回的内容:

This is what .get_loc() and .get_indexer() return:

In [6]: np.sort(idx.get_loc(900))
Out[6]: array([    0,     3,     6, ..., 29991, 29994, 29997])

这篇关于在 pandas Intervalindex中查找匹配间隔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆