2017-08-19 21 views
1

我想趕緊寫點類,其中底層2D numpy.matrix的每一列被分配到一個屬性 ,這樣我可以寫這樣的東西很容易:擴展numpy.matrix會產生__new__和__class__問題嗎?

points  = Points(np.mat(np.ones((2,3))), names=["a","b","c"]) 
points.a = points.b + points.c 
points["a"] = points["b"] + points["c"] 

我想出了這樣的「猴子補丁」

class Points(np.matrixlib.defmatrix.matrix): 

    def __new__(cls, *args, names=[], **kwargs): 
     o = np.matrixlib.defmatrix.matrix.__new__(cls, *args, **kwargs) 
     o.__class__ = Points 
     return o 

    def __init__(self, *args, names=[], **kwargs): 
     # Set the attribute self.<pointName> 
     # to a reference of the corresponding column 
     for i,name in enumerate(names): 
      self.__setattr__(name, self[:,i]) 

我想知道是否有做暴力破解o.__class__ = Points的更好的方法。 我需要這樣做,因爲Points.__init__不會被調用,因爲type(o) != Points

全班同學正在這裏 https://gist.github.com/gabyx/9392992d11bf8550e44002ac7f1ecaaf

+1

爲什麼不只是使用[pandas DataFrame](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html)或[NumPys結構化數組](https://docs.scipy .ORG/DOC/numpy的/用戶/ basics.rec.html)?這些列已經有了列和行訪問操作。 – MSeifert

+0

記錄數組(np.rec.array)將爲您提供字段訪問的點符號。 – Eric

+0

我也這麼認爲,但是結構化數組很難操縱,讓我們說通過矩陣很容易地轉換所有點... – Gabriel

回答

0

這在Python 3.5.1對我的作品,與numpy.version.full_version == '1.8.0'

import numpy 

class Points(numpy.matrixlib.defmatrix.matrix): 
    def __new__(subtype, data, names=[], **kwargs): 
     tmp = super(Point, subtype).__new__(subtype, data, **kwargs) 

     for i, name in zip(range(tmp.shape[0]), names): 
      tmp.__setattr__('point_{}'.format(name), tmp[i]) 

     return tmp 


arr = numpy.arange(6).reshape((-1, 3)) 

a = Points(arr, names='abc') 
print(a) 
print(a.point_a, a.point_b) 

貌似沒有必要Points.__init__因爲所有的參數傳遞在所有直接到Points.__new__,然後到numpy.matrixlib.defmatrix.matrix.__new__。此外,numpy.matrixlib.defmatrix.matrix.__init__忽略提供的所有參數。但是,如果需要,可以將__setattr__邏輯移動到Points.__init__

+0

爲什麼不用'用於行,名稱爲zip(tmp,名稱)'? – Eric

+0

@Eric,對,看起來更好,我只是從OP的代碼複製 – ForceBru

+0

這裏的問題是,返回的'tmp'是類型:'''numpy.matrixlib.defmatrix.matrix''這很奇怪。我不明白爲什麼 – Gabriel