用于偏移量更改的python numpy ndarray子类化

用于偏移量更改的python numpy ndarray子类化,python,numpy,subclass,offset,Python,Numpy,Subclass,Offset,我正在开发一个处理传入数据的框架 数据从套接字接收并使用移位等方式添加到numpy数组a(用作缓冲区): A[:-1] = A[1:] A[-1] = value 框架允许将处理单元作为类加载,这些类可以使用指向A的数组视图访问传入数据。每次在A中接收和存储新数据时,都会调用一个方法execute(): def execute(self,): newSample = self.data[-1] 重要的是,新样本始终位于索引=-1下。 用户还可以在函数中创建自己的数组视图: def _

我正在开发一个处理传入数据的框架

数据从套接字接收并使用移位等方式添加到numpy数组a(用作缓冲区):

A[:-1] = A[1:]
A[-1] = value
框架允许将处理单元作为类加载,这些类可以使用指向A的数组视图访问传入数据。每次在A中接收和存储新数据时,都会调用一个方法
execute()

def execute(self,):
    newSample = self.data[-1]
重要的是,新样本始终位于
索引=-1
下。 用户还可以在
函数中创建自己的数组视图:

def __init__(self,):
    self.myData = self.data[-4:]  # view that contains last 4 samples
当我移动数组A并在末尾添加新值时,一切都很好。但是,对于离线测试,我希望在框架开始时加载所有数据,并像以前一样运行所有其他内容(即实现数据处理的相同类)。 当然,我可以再次使用zeros数组创建一个缓冲区,并用新值对其进行移位。但是,这涉及到在两个阵列之间复制数据,这是绝对不必要的—需要时间和内存

我想的是提供一种方法来更改numpy数组的边界或更改.data指针。但是,不允许使用所有解决方案或导致警告消息

最后,我尝试更改数组A的内部偏移量,这样我可以提高它,从而为算法提供更多数据。重要的是,
self.data[-1]
必须始终指向新出现的示例,并且应该使用标准的numpy数组API

我将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实现,因为我需要使用标准的numpyapi

我也试过:

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=np.数组([1,2,3,4,5,6,7,8,9,10])
b=a.视图()[5:]
打印(a.数据)#
打印(b.data)#它们指向相同的内存开始!
打印(np.byte_bounds(a))#(5023782450237904)
打印(np.byte_界限(b))#(5023786450237904),但byte_界限不同
考虑到这一点,我会说我需要创建一个数组
a
的视图,并对其进行扩展(或者至少像在
a
上的窗口一样移动它)。
但是,我所有试图更改字节\u界限的尝试都没有带来任何效果。

我钦佩你的勇气,但我确信,对numpy数组进行子分类对于解决你的问题来说是过火了,会让你非常头痛。最终,它可能会在某些地方造成性能损失,远远超过您试图避免的阵列复制

为什么不将切片(即
[-4://code>或
切片(-4,None)
)作为
\uuuuu init\uuuuuu
函数或类属性的参数,并在测试中重写它

def __init__(self, lastfour=slice(-4, None)):
    self.myData = self.data[lastfour]