Я работаю над платформой для обработки входящих данных.
Данные получены из сокета и добавлены в массив n (для использования в качестве буфера) с использованием сдвига, например:
A[:-1] = A[1:]
A[-1] = value
Каркас позволяет загружать единицы обработки в виде классов, которые имеютдоступ к входящим данным с использованием представления массива, указывающего на A. Каждый раз, когда новые данные принимаются и сохраняются в A, вызывается метод execute()
:
def execute(self,):
newSample = self.data[-1]
Важно то, что новый образец всегда находится под index = -1
.Пользователь также может создавать свои собственные представления массива в функции __init__
:
def __init__(self,):
self.myData = self.data[-4:] # view that contains last 4 samples
Все работает хорошо, когда я перемещаю массив A и добавляю новое значение в конце.Однако для автономного тестирования я хочу загрузить все данные в начале фреймворка и запустить все остальное, как раньше (то есть те же классы, реализующие обработку данных).Конечно, я могу снова создать буфер A, используя массив нулей, и переместить его с новыми значениями.Однако это включает в себя копирование данных между двумя массивами, что абсолютно не нужно - требует времени и памяти.
Я думал о том, чтобы предоставить способ изменить границы массива numpy или изменить A.data.указатель.Тем не менее, все решения не разрешены или приводят к появлению предупреждающего сообщения.
Наконец, я пытаюсь изменить внутреннее смещение массива A, чтобы я мог его увеличить и, таким образом, сделать больше данных доступным для алгоритмов.Что важно, self.data[-1]
должен всегда указывать на вновь появившийся образец, и должен использоваться стандартный API для массива numpy.
У меня есть подкласс np.ndarray:
class MyArrayView(np.ndarray):
def __new__(cls, input_array):
obj = np.asarray(input_array).view(cls)
# add the new attribute to the created instance
obj._offset = 0
# Finally, we must return the newly created object:
return obj
def __array_finalize__(self, obj):
if obj is None:
return
self._offset = getattr(obj, '_offset', None)
def advance_index(self):
self._offset += 1
def __str__(self):
return super(MyArrayView, self[:]).__str__()
def __repr__(self):
return super(MyArrayView, self[:]).__repr__()
def __getitem__(self, idx):
if isinstance(idx, slice):
start = 0
stop = self._offset
step = idx.step
idx = slice(start, stop, step)
else:
idx = self._offset + idx
return super(MyArrayView, self).__getitem__(idx)
, что позволяет мнесделать следующее:
a = np.array([1,2,3,4,5,6,7,8,9,10])
myA = MyArrayView(a)
b = myA
print("b :", b)
for i in range(1,5):
myA.advance_index()
print(b[:], b[-1])
print("b :", b)
print("b + 10 :", b + 10)
print("b[:] + 20 :", b[:] + 20)
и дать следующий вывод:
b : []
[1] 1
[1 2] 2
[1 2 3] 3
[1 2 3 4] 4
b : [1 2 3 4]
b + 10 : [11 12 13 14]
b[:] + 20 : [21 22 23 24]
пока все хорошо.Однако если я проверю форму:
print("shape", b[:].shape) # shape (4,)
print("shape", b.shape) # shape (10,)
, то в этих двух случаях она будет другой.Я попытался изменить его, используя: shape=(self.internalIndex,)
, но это приводит меня только к сообщению об ошибке.
Я хочу спросить, считаете ли вы, что это правильный путь, и я требую только перегрузкифункции в классе np.ndarray.Или я должен полностью отказаться от этого решения и вернуться к смещению массива с новым образцом?Или это может быть возможно достичь с помощью стандартной реализации np.ndarray, так как мне нужно использовать стандартный Numpy API.
Я также попробовал это:
a = np.array([1,2,3,4,5,6,7,8,9,10])
b = a.view()[5:]
print(a.data) # <memory at 0x7f09e01d8f48>
print(b.data) # <memory at 0x7f09e01d8f48> They point to the same memory start!
print(np.byte_bounds(a)) # (50237824, 50237904)
print(np.byte_bounds(b)) # (50237864, 50237904) but the byte_bounds are different
Так что, имея это в виду,Я бы сказал, что мне нужно создать представление массива a
и расширить его (или хотя бы переместить как окно поверх a
).Однако все мои попытки изменить границы byte_bounds не принесли никаких результатов.