Python Pandas:使用小于给定值的元素获取第一行的有效方法

Python Pandas:使用小于给定值的元素获取第一行的有效方法,python,pandas,Python,Pandas,我想知道在pandas中是否有一种有效的方法来实现这一点:给定一个数据帧,第一行中小于给定值的是什么?例如,假设: addr 0 4196656 1 4197034 2 4197075 3 4197082 4 4197134 小于4197080的第一个值是什么?我希望它返回4197075的行。 一个解决方案是首先按4197080进行过滤,然后取最后一行,但这看起来是一个非常慢的O(N)操作(首先构建一个数据帧,然后取最后一行),而二进制搜索将取O(logN) 获取第一个较

我想知道在pandas中是否有一种有效的方法来实现这一点:给定一个数据帧,第一行中小于给定值的是什么?例如,假设:

      addr
0  4196656
1  4197034
2  4197075
3  4197082
4  4197134
小于4197080的第一个值是什么?我希望它返回4197075的行。 一个解决方案是首先按4197080进行过滤,然后取最后一行,但这看起来是一个非常慢的O(N)操作(首先构建一个数据帧,然后取最后一行),而二进制搜索将取O(logN)

获取第一个较小的值非常缓慢:

%timeit df.addr[ df.addr < 57830391].tail(1)
100 loops, best of 3: 7.9 ms per loop
但仍然远不及二进制搜索的速度:

%timeit bisect(num, 57830391, 0, len(num))
100000 loops, best of 3: 6.53 µs per loop
有更好的方法吗?

这需要0.14.0

请注意,该帧未排序

In [16]: s = df['addr']
找到低于要求的最大值

In [18]: %timeit s[s<5783091]
100 loops, best of 3: 9.01 ms per loop

In [19]: %timeit s[s<5783091].nlargest(1)
100 loops, best of 3: 11 ms per loop
如果只是搜索已排序的序列,请使用
searchsorted
。请注意,您必须使用numpy版本(例如,在
上操作.values
。系列版本将在0.14.1中定义)


使用对分法似乎很快。那就这样吧。为什么这个时差实际上在实用性上很重要?你这样做过多次吗?(他们的方法更好)。您正在解决的实际问题是什么?仅供参考,排序是目前为止最慢的操作。您可以尝试使用不排序的
nsmallest
。(0.14.0中新增)但我只是对查询进行计时,而不是排序。。是的,我将多次进行此查询,可能是数千次或数百万次。这里要解释的实际问题有点复杂。。这只是一般算法的一部分。然后看看我的答案。如果你知道它是排序的,那么这是一个很好的查询时间。使用
searchsorted
要快得多,因为
bisect
在numpy数组上的操作和
searchsorted
一样有效。是的,bisect看起来非常快,比我在pandas中能做的任何事情都快得多。问题是我是否能以同样快的速度制作熊猫。
%timeit bisect(num, 57830391, 0, len(num))
100000 loops, best of 3: 6.53 µs per loop
In [16]: s = df['addr']
In [18]: %timeit s[s<5783091]
100 loops, best of 3: 9.01 ms per loop

In [19]: %timeit s[s<5783091].nlargest(1)
100 loops, best of 3: 11 ms per loop
In [32]: x = np.random.randint(0, 10**8, 10**6)

In [33]: def f(x):
   ....:     x.copy().sort()
   ....:     

In [35]: %timeit f(x)
10 loops, best of 3: 67.2 ms per loop
In [41]: %timeit  s.values.searchsorted(5783091)
100000 loops, best of 3: 2.5 µs per loop