首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何通过索引获取deque元素?

如何通过索引获取deque元素?
EN

Stack Overflow用户
提问于 2018-06-24 04:24:43
回答 1查看 2.9K关注 0票数 4

我有以下的deque对象:

代码语言:javascript
复制
test = deque([np.zeros((4,1,1))+0.5] * 25)

所以有25个不同形状的数组,我将在对象中添加,在另一端弹出旧的,等等。

在某些情况下,我会想要选择我的deque中的一个元素子集:

代码语言:javascript
复制
>>> idx = np.round(np.linspace(0, 20, 4, dtype='int'))
>>> idx
array([ 0,  6, 13, 20])

所以我想要这些索引。我试过了:

代码语言:javascript
复制
>>> 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

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

编辑--

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

如果所有东西都只有一个形状模糊的(N, H,W,3)数组就好了,但是我不知道如何获得高效的队列功能,所以我选择了deque

EN

回答 1

Stack Overflow用户

发布于 2018-06-24 05:32:51

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

因此,使用NumPy可能是一个更好的主意(对于更大的deque大小来说也更有效),而不是deque。

现在,您可以在ndarray周围滚动自己的类似deque的环形缓冲区接口类,该ndarray管理缓冲区的大小、左/右索引等。或者Eric Weiser已经发布了numpy_ringbuffer,它似乎非常适合您的问题。

演示

代码语言:javascript
复制
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版本中获得最小的deque界面。您还可以在基础数组上使用NumPy索引。

代码语言:javascript
复制
In [90]: r[[0, 2]]
Out[90]: 
array([[[12., 13.],
        [14., 15.]],

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

与NumPy中幼稚的类deque操作相比,它会快得多,因为它只是在任何可能的地方操作左/右索引。

代码语言:javascript
复制
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)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51004753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档