gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 02:20:16 25 4
gpt4 key购买 nike

我想知道在 pandas 中是否有一种有效的方法可以做到这一点:给定一个数据框,第一行小于给定值的行是什么?例如,给定:

      addr
0 4196656
1 4197034
2 4197075
3 4197082
4 4197134

第一个小于 4197080 的值是多少?我希望它只返回 4197075 所在的行。一个解决方案是先按 4197080 过滤,然后取最后一行,但这看起来是一个非常慢的 O(N) 操作(首先构建一个数据帧,然后取其最后一行),而二进制搜索将花费 O (logN).

df.addr[ df.addr < 4197080].tail(1)

我计时,并创建了 df.addr[ df.addr < 4197080]或多或少与 df.addr[ df.addr < 4197080].tail(1) 相同,强烈暗示它在内部首先构建一个完整的 df。

num = np.random.randint(0, 10**8, 10**6)
num.sort()
df = pd.DataFrame({'addr':num})
df = df.set_index('addr', drop=False)
df = df.sort_index()

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

%timeit df.addr[ df.addr < 57830391].tail(1)
100 loops, best of 3: 7.9 ms per loop

使用 lt 可以稍微改善一下:

%timeit df.lt(57830391)[-1:]
1000 loops, best of 3: 853 µs 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

所以这比实际执行完整排序然后索引要快。.copy 是为了避免就地排序产生偏差。

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

如果您只是搜索一个已经排序的系列,那么使用searchsorted。注意一定要使用numpy版本(比如操作.values,系列版本会在0.14.1定义)

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

关于python - Pandas:使用小于给定值的元素获取第一行的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24264424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com