ここでCスタイルの考え方から一歩後退する必要があると思います。挿入ごとにリングバッファを更新することは、決して効率的ではありません。リングバッファは、numpy配列が要求する連続したメモリブロックインターフェイスとは根本的に異なります。あなたがやりたいと言っているfftを含みます。
自然な解決策は、パフォーマンスのためにメモリを少し犠牲にすることです。たとえば、バッファに保持する必要のある要素の数がNの場合、N + 1024(または適切な数)の配列を割り当てます。次に、1024回の挿入ごとにN個の要素を移動するだけで済み、直接利用可能なN個の要素の連続したビューが常に表示されます。
編集:これは上記を実装するコードスニペットであり、優れたパフォーマンスを提供するはずです。ただし、要素ごとではなく、チャンクで追加することをお勧めします。そうしないと、リングバッファの実装方法に関係なく、numpyを使用することによるパフォーマンス上の利点がすぐに無効になります。
import numpy as np
class RingBuffer(object):
def __init__(self, size, padding=None):
self.size = size
self.padding = size if padding is None else padding
self.buffer = np.zeros(self.size+self.padding)
self.counter = 0
def append(self, data):
"""this is an O(n) operation"""
data = data[-self.padding:]
n = len(data)
if self.remaining < n: self.compact()
self.buffer[self.counter+self.size:][:n] = data
self.counter += n
@property
def remaining(self):
return self.padding-self.counter
@property
def view(self):
"""this is always an O(1) operation"""
return self.buffer[self.counter:][:self.size]
def compact(self):
"""
note: only when this function is called, is an O(size) performance hit incurred,
and this cost is amortized over the whole padding space
"""
print 'compacting'
self.buffer[:self.size] = self.view
self.counter = 0
rb = RingBuffer(10)
for i in range(4):
rb.append([1,2,3])
print rb.view
rb.append(np.arange(15))
print rb.view #test overflow