2012-02-29 18 views
1

假設下給出的類定義:如何編寫一個行爲類似numpy.ndarray的類,而不需要創建numpy.ndarray子類?

class Numeric(object): 
    def __init__(self, signal): 
    self.signal = signal 

現在,與Numeric不從numpy.ndarray繼承的要求,我怎麼也得延長該定義,Numeric表現得像numpy.ndarray

編輯:signal應該是np.ndarray(或類似的,像quantities.Quantity)。我心裏有以下scenarious:

import numpy as np 
import quantities as pq 

a = Numeric(pq.Quantity([1,2,3], 'mV')) 
b = Numeric(pq.Quantity([1,3,5], 's')) 
c = Numeric(np.array([10,20,30])) 

a = Numeric(np.array([1,2,3])) 
b = Numeric(np.array([1,3,5])) 
a * c 
a * b 
a * np.array([3,4,5]) 

和:

import matplotlib.pyplot as plt 
plt.plot(b) 
+1

這個要求來自哪裏? – wim 2012-02-29 12:24:55

+5

是否有任何你想要的ndarray行爲的特定位?這是一件相當大的事情。 – 2012-02-29 12:53:53

+4

因爲像'asarray'這樣的一些Numpy操作取決於他們是否得到一個'ndarray'實例或其他東西,所以你不會得到完整的'ndarray'行爲。 – 2012-02-29 13:00:06

回答

1

隨着裝飾爲適應numpy -functions和內Numeric__array__的實現,我可以解決大部分問題:

def adapt_signal_functions(cls): 
    def generateAdjustedFunction(functionName): 
    print functionName 
    def foo(self, *args, **kwargs): 
     function = getattr(self.signal.__class__, functionName) 
     return function(self.signal, *args, **kwargs) 
    return foo 
    functionNames = [ 
     '_get_units', 
     '_set_units', 
     'rescale', 
     'ptp', 
     'clip', 
     'copy', 
     'compress', 
     'conj', 
     'cumprod', 
     'cumsum', 
     'diagonal', 
     'dot', 
     'flatten', 
     'getfield', 
     'round', 
     'trace', 
     'max', 
     'mean', 
     'min', 
     'newbyteorder', 
     'prod', 
     'ravel', 
     'reshape', 
     'resize', 
     'round', 
     'std', 
     'sum', 
     'trace', 
     'transpose', 
     'var', 
     '__getitem__', 
     '__getslice__', 
     '__abs__', 
     # 
     '__add__', 
     '__div__', 
     '__divmod__', 
     '__floordiv__' 
     '__mod__', 
     '__mul__', 
     '__pow__', 
     '__sub__', 
     # 
     '__radd__', 
     '__div__', 
     '__divmod__', 
     '__rfloordiv__', 
     '__rmod__', 
     '__imul__', 
     #'__rmul__', 
     '__rpow__', 
     '__rsub__', 
     ] 
    for functionName in functionNames: 
    foo = generateAdjustedFunction(functionName) 
    setattr(cls, functionName, foo) 
    return cls 


@adapt_signal_functions 
class Numeric(object): 
    def __init__(self, signal): 
    self.signal = signal 
    self.adapt_quantity() 

    def adapt_quantity(self): 
    if hasattr(self.signal, '_dimensionality'): 
     self._dimensionality = self.signal._dimensionality 
     self.dimensionality = self.signal.dimensionality 

    def __array__(self): 
    return self.signal 

我可以這樣做:

import numpy as np 
import quantities as pq 

a = Numeric(pq.Quantity([1,2,3], 'mV')) 
b = Numeric(pq.Quantity([1,3,5], 's')) 
c = Numeric(np.array([10,20,30])) 
n = np.array([1,2,3]) 

a * a 
a * c 
a * n 
a.max() 

print type(a * n) == type(a.signal * n) 
# >>> True 
print type(a * c) == type(a.signal * c.signal) 
# >>> True 

返回類型對應於等效返回類型Numeric.signal

一個問題仍然存在:

print type(n * a) == type(n * a.signal) 
# >>> False 

任何想法,如何解決?

+1

什麼是」數量「?在SQLAlchemy中定義?或者你自己定義的東西?(或其他東西?) – 2012-02-29 17:02:03

+0

@EdwardLoper - 我會假設它是這個單位轉換庫:http://packages.python.org/quantities/user/tutorial.html – 2012-02-29 17:43:51

+0

正是如此, 'pq.Quantity'繼承自'numpy.ndarray'。 – 2012-03-01 19:13:17

相關問題