问题描述
简短版本:
如何在没有 O(n) 内存复制的情况下做到这一点
start = 2 # \/ start points here
input = np.array([4,5,1,2,3])
output = np.array([1,3,4,5]) # output doesn't need to be memory contiguous,a view is just fine
长版:
我正在尝试基于 numpy.ndarray 实现一个固定长度的 FIFO 缓冲区,用于硬件模拟。
我的目标是实现 O(1)(或至少小于 O(n))的入队/出队,最重要的是:以正确的顺序获取 numpy 数组。
我最终使用一个指针 start
来指向 FIFO 的第一个元素,因此入队/出队只是快速的单一分配/索引。
但问题是,当我想将整个 FIFO 用作 numpy.ndarray 并进行一些数学运算(如 np.dot(signal,fifo))时,我无法找到一种无需 O(n) 操作即可获得相应数组的方法。
这听起来像是一个已经发明的轮子,所以我在网上搜索并尝试了一些东西,但这些都不适合我的需要:
-
input[1:] = input[:-1]; input[0] = new_val
迄今为止最简单但最有效的方法,但仍然是 O(n) - collection.deque:入队/出队性能良好,但与其他 numpy 数组一起工作需要很长时间(似乎 numpy 会先将 deque 转换为 numpy.ndarray,然后进行数学运算,这将花费很多时间)
- indexing:
input[np.arange(start,start+size)%size]
这是高级索引,因此它返回新数组,而索引数组创建部分使它更慢 -
np.r_[input[start:],input[:start]]
,当缓冲区很大时比索引更好,但仍然是 O(n) -
np.roll(input,-start)
,O(n) 和更慢 -
np.concatenate([input[start:],input[:start]])
,O(n),比naive方式慢但比其他方式快
由于原始数组是连续的,所以我也尝试使用 strides/shape 技巧来创建原始数组的视图,但两者都不起作用。
所以我是来这里寻求帮助的,还是必须是 O(n)?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)