3

我想要一个系统,其中我有一个“数据类”,它有一些数组和一个“选择类”,它具有相同的数组名称,其数据只是数据类中数组子集的一个视图。哪些应该由选择类的实例确定。如果更改了 Selection 类的实例中的某些内容,则应该将其映射回相应的 Data 类并使事情变得非常困难,不仅选择类中的数组应该是真正的 ndarray(因此所有方法都应该起作用),它们也应该只是对原始数据的看法或仅根据需要创建。

到目前为止我创建的脚手架是

import numpy as np

class DataObj():
    def __init__( self, Data_dict ):
        self.arrays = [ n for n,d in Data_dict.iteritems() ]
        for n,d in Data_dict.iteritems():
            setattr( self, n, d )

class Darray(np.ndarray):
    def __new__(cls, input_array, SelObj, *args, **kwargs):
        obj = np.asarray(input_array[ SelObj.selA, SelObj.selB ]).view(cls)
        obj.SelObj = SelObj
        return obj

    def __array_finalize__(self, obj):
        if obj is None: return  

    def __getitem__(self, index):
        return super(Darray, self).__getitem__(index)      


class SelObj():
    def __init__(self, DataObj, selA, selB):
        self.selA = selA
        self.selB = selB
        self.DataObj = DataObj

        for n in DataObj.arrays:
            Darr = Darray( getattr( self.DataObj, n), self )
            setattr( self, n, Darr )

### creating some objects
DObj  = DataObj({ "X":ones((10,20)),
                  "Y":zeros((10,20)),
                  "Z":arange(10*20).reshape(10,20) })

SObj1 = SelObj( DObj, array([1,3,4]), slice(None,None,2) )
SObj2 = SelObj( DObj, array([4,5,7]), slice(None,2,None) )
SObj3 = SelObj( DObj, array([1,3,4]), slice(None)        )

这有效,但现在如果做

SObj1.X = 10

它失去了连接,只有一个 10 而不是原始数组。即使我做了一些真正有意义的事情,比如

SObj1.X[0,0] = 10.

这不会出现在 DObj 中(因为input_array[ SelObj.selA, SelObj.selB ]我创建了数组的副本)。Ans 现在每个 SObj 都将拥有自己的数据,这些数据最终会阻塞内存。

我知道我想要的并不容易,但我仍然想这样做。我也在研究属性并使每个 Darray 成为 SObj 的属性;每当调用该属性时就按需进行切片。然而,事情就像

SObj1.X[0,0] = 10.

将不再起作用,因为该属性已经切片,并且不再映射回附加切片。

我将非常感谢任何指向此结构解决方案的提示。

大卫

4

1 回答 1

0

如果你想要一个像

SObj1.X = 10

要更改某些遥远来源的值,您应该覆盖类__setattr__中的方法SelObj。像这样:

class SelObj():
    def __init__(self, DataObj, selA, selB):
        self.selA = selA
        self.selB = selB
        self.DataObj = DataObj

        for n in DataObj.arrays:
            Darr = Darray( getattr( self.DataObj, n), self )
            setattr( self, n, Darr )

    def __setattr__(self, name, value):
        setattr(self.DataObj, name, value) # updates the source of the data
        super(SelObj, self).__setattr__(name, value) # updates the representation
于 2013-10-16T09:06:36.827 回答