JDS*_*JDS 7 python arrays queue numpy deque
我有以下双端队列对象:
test = deque([np.zeros((4,1,1))+0.5] * 25)
Run Code Online (Sandbox Code Playgroud)
所以有 25 个某种形状的数组,我将追加对象,在另一端弹出旧的数组,等等。
在某些时候,我想要在双端队列中选择元素的子集:
>>> idx = np.round(np.linspace(0, 20, 4, dtype='int'))
>>> idx
array([ 0, 6, 13, 20])
Run Code Online (Sandbox Code Playgroud)
所以我想要那些索引。我试过:
>>> 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
Run Code Online (Sandbox Code Playgroud)
也许deque不支持这种类型的索引操作。idx如何轻松(高效)地获取from中的元素列表test?
编辑 -
有关我最初目标的更多信息。我有一个 3D numpy 数组列表,即(N, H,W,3)实时地将一个新的 3D 数组移入 的列表中N,即一个新的大小数组(H,W,3)(如队列)移入 N 的列表中。
如果能为所有内容都提供一个 numpy 形状数组就好了(N, H,W,3),但我不知道如何获得高效的队列功能,所以我选择了deque.
为了直接回答您的问题,您可以使用与列表相同的可迭代索引来索引双端队列 - [test[i] for i in idx]。但是双端队列随机查找O(n)(这对于较大的双端队列可能更重要),如果你想对双端队列进行 NumPy 式索引,你将无法做到。从您的问题描述来看,您似乎正在寻找环形缓冲区。
因此,坚持使用 NumPy 可能比使用双端队列更好(并且对于较大的双端队列更有效)。
\n\n现在,您可以围绕 ndarray 滚动自己的类似双端队列的环形缓冲区接口类,该类管理缓冲区的大小、左/右索引等。或者 Eric Weiser 已经发布了它,numpy_ringbuffer它似乎非常适合您的问题。
演示
\n\nIn [83]: from numpy_ringbuffer import RingBuffer\n\nIn [84]: # RingBuffer w/ capacity 3, extra dimensions (2, 2)\n ...: r = RingBuffer(capacity=3, dtype=(float, (2, 2)))\n\nIn [85]: # fill our buffer up\n ...: r.extendleft(np.arange(12, dtype=float).reshape(3, 2, 2))\n\nIn [86]: r.is_full\nOut[86]: True\n\nIn [87]: r\nOut[87]: \n<RingBuffer of array([[[ 0., 1.],\n [ 2., 3.]],\n\n [[ 4., 5.],\n [ 6., 7.]],\n\n [[ 8., 9.],\n [10., 11.]]])>\n\nIn [88]: r.appendleft(np.arange(12, 16).reshape(2, 2))\n\nIn [89]: r\nOut[89]: \n<RingBuffer of array([[[12., 13.],\n [14., 15.]],\n\n [[ 0., 1.],\n [ 2., 3.]],\n\n [[ 4., 5.],\n [ 6., 7.]]])>\nRun Code Online (Sandbox Code Playgroud)\n\n您将获得一个最小的双端队列接口,带有append, extend,pop。您还可以在底层数组上使用 NumPy 索引。
In [90]: r[[0, 2]]\nOut[90]: \narray([[[12., 13.],\n [14., 15.]],\n\n [[ 4., 5.],\n [ 6., 7.]]])\nRun Code Online (Sandbox Code Playgroud)\n\n与 NumPy 中类似双端队列操作的简单方法相比,它会快得多,因为它只是尽可能地操作左/右索引。
\n\nIn [91]: arr = np.random.randn(10**7).reshape(10**5, 10, 10)\n\nIn [92]: r = RingBuffer(capacity=arr.shape[0],\n ...: dtype=(float, arr.shape[1:]))\n ...: \n\nIn [93]: %%timeit r.extendleft(arr); s = np.random.randn(10, 10)\n ...: r.appendleft(s)\n ...: r.append(s)\n ...: \n4.08 \xc2\xb5s \xc2\xb1 66.5 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n\nIn [94]: %%timeit A=arr.copy(); s = np.random.randn(10, 10)\n ...: A[1:] = A[:-1]\n ...: A[0] = s\n ...: A[:-1] = A[1:]\n ...: A[-1] = s\n ...: \n91.5 ms \xc2\xb1 231 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\nRun Code Online (Sandbox Code Playgroud)\n