gpt4 book ai didi

python - 如何通过索引获取双端队列元素?

转载 作者:太空宇宙 更新时间:2023-11-03 15:44:14 26 4
gpt4 key购买 nike

我有以下双端队列对象:

test = deque([np.zeros((4,1,1))+0.5] * 25)

所以有 25 个某种形状的数组,我将追加对象,在另一端弹出旧对象,等等。

有时我想在我的双端队列中选择一个元素子集:

>>> idx = np.round(np.linspace(0, 20, 4, dtype='int'))
>>> idx
array([ 0, 6, 13, 20])

所以我想要那些指标。我试过了:

>>> test[idx]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: only integer scalar arrays can be converted to a scalar index

也许双端队列不支持这种类型的索引操作。我如何轻松(高效)从 test 获取 idx 中的元素列表?

编辑——

关于我最初目标的更多信息。我有一个 3D numpy 数组列表,即 (N, H,W,3) 并且我实时将一个新的 3D 数组转移到 N 列表中,即,一个大小为 (H,W,3) 的新数组被转移(如队列)到 N 的列表中。

如果所有的东西都有一个形状为 (N, H,W,3) 的 numpy 数组就好了,但我不知道如何获得高效的队列功能,所以我去了使用 双端队列

最佳答案

为了直接回答你的问题,你用一个可迭代的索引索引一个双端队列,就像你做一个列表一样 - [test[i] for i in idx]。但是双端队列随机查找是 O(n)(对于较大的双端队列来说可能更重要),如果你想对双端队列进行 NumPy 风格的索引,你将无法做到。从您的问题描述来看,您似乎也在寻找环形缓冲区。

因此,完全不使用双端队列,坚持使用 NumPy 可能是一个更好的主意(并且对于更大的双端队列更有效)。

现在您可以围绕管理缓冲区大小、左/右索引等的 ndarray 滚动自己的类似双端队列的环形缓冲区接口(interface)类。或者 Eric Weiser 已经发布了 numpy_ringbuffer这似乎很适合您的问题。

演示

In [83]: from numpy_ringbuffer import RingBuffer

In [84]: # RingBuffer w/ capacity 3, extra dimensions (2, 2)
...: r = RingBuffer(capacity=3, dtype=(float, (2, 2)))

In [85]: # fill our buffer up
...: r.extendleft(np.arange(12, dtype=float).reshape(3, 2, 2))

In [86]: r.is_full
Out[86]: True

In [87]: r
Out[87]:
<RingBuffer of array([[[ 0., 1.],
[ 2., 3.]],

[[ 4., 5.],
[ 6., 7.]],

[[ 8., 9.],
[10., 11.]]])>

In [88]: r.appendleft(np.arange(12, 16).reshape(2, 2))

In [89]: r
Out[89]:
<RingBuffer of array([[[12., 13.],
[14., 15.]],

[[ 0., 1.],
[ 2., 3.]],

[[ 4., 5.],
[ 6., 7.]]])>

您将获得一个带有appendextendpop 和left 版本的最小双端队列接口(interface)。您还可以在底层数组上使用 NumPy 索引。

In [90]: r[[0, 2]]
Out[90]:
array([[[12., 13.],
[14., 15.]],

[[ 4., 5.],
[ 6., 7.]]])

与 NumPy 中类似双端队列操作的朴素方法相比,它会更快,因为它只是尽可能地操纵左/右索引。

In [91]: arr = np.random.randn(10**7).reshape(10**5, 10, 10)

In [92]: r = RingBuffer(capacity=arr.shape[0],
...: dtype=(float, arr.shape[1:]))
...:

In [93]: %%timeit r.extendleft(arr); s = np.random.randn(10, 10)
...: r.appendleft(s)
...: r.append(s)
...:
4.08 µs ± 66.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [94]: %%timeit A=arr.copy(); s = np.random.randn(10, 10)
...: A[1:] = A[:-1]
...: A[0] = s
...: A[:-1] = A[1:]
...: A[-1] = s
...:
91.5 ms ± 231 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

关于python - 如何通过索引获取双端队列元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51004753/

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