Solbrig,Jeremy
2016-01-26 05:43:34 UTC
Hello,
<http://stackoverflow.com/questions/35005569/behavior-of-ufuncs-and-mathematical-operators-differ-for-subclassed-maskedarray>
Much of what is below was copied from this stack overflow question.
I am attempting to subclass numpy.ma.MaskedArray. I am currently using Python v2.7.10. The problem discussed below does not occur in Numpy v1.9.2, but does occur in all versions of Numpy v1.10.x.
In all versions of Numpy v1.10.x, using mathematical operators on my subclass behaves differently than using the analogous ufunc. When using the ufunc directly (e.g. np.subtract(arr1, arr2)), __array_prepare__, __array_finalize__, and __array_wrap__ are all called as expected, however, when using the symbolic operator (e.g. arr1-arr2) only __array_finalize__ is called. As a consequence, I lose any information stored in arr._optinfo when a mathematical operator is used.
Here is a code snippet that illustrates the issue.
#!/bin/env python
import numpy as np
from numpy.ma import MaskedArray, nomask
class InfoArray(MaskedArray):
def __new__(cls, info=None, data=None, mask=nomask, dtype=None,
copy=False, subok=True, ndmin=0, fill_value=None,
keep_mask=True, hard_mask=None, shrink=True, **kwargs):
obj = super(InfoArray, cls).__new__(cls, data=data, mask=mask,
dtype=dtype, copy=copy, subok=subok, ndmin=ndmin,
fill_value=fill_value, hard_mask=hard_mask,
shrink=shrink, **kwargs)
obj._optinfo['info'] = info
return obj
def __array_prepare__(self, out, context=None):
print '__array_prepare__'
return super(InfoArray, self).__array_prepare__(out, context)
def __array_wrap__(self, out, context=None):
print '__array_wrap__'
return super(InfoArray, self).__array_wrap__(out, context)
def __array_finalize__(self, obj):
print '__array_finalize__'
return super(InfoArray, self).__array_finalize__(obj)
if __name__ == "__main__":
arr1 = InfoArray('test', data=[1,2,3,4,5,6])
arr2 = InfoArray(data=[0,1,2,3,4,5])
diff1 = np.subtract(arr1, arr2)
print diff1._optinfo
diff2 = arr1-arr2
print diff2._optinfo
If run, the output looks like this:
$ python test_ma_sub.py
#Call to np.subtract(arr1, arr2) here
__array_finalize__
__array_finalize__
__array_prepare__
__array_finalize__
__array_wrap__
__array_finalize__
{'info': 'test'}
#Executing arr1-arr2 here
__array_finalize__
{}
Currently I have simply downgraded to 1.9.2 to solve the problem for myself, but have been having difficulty figuring out where the difference lies between 1.9.2 and 1.10.0.
Thanks,
Jeremy
<http://stackoverflow.com/questions/35005569/behavior-of-ufuncs-and-mathematical-operators-differ-for-subclassed-maskedarray>
Much of what is below was copied from this stack overflow question.
I am attempting to subclass numpy.ma.MaskedArray. I am currently using Python v2.7.10. The problem discussed below does not occur in Numpy v1.9.2, but does occur in all versions of Numpy v1.10.x.
In all versions of Numpy v1.10.x, using mathematical operators on my subclass behaves differently than using the analogous ufunc. When using the ufunc directly (e.g. np.subtract(arr1, arr2)), __array_prepare__, __array_finalize__, and __array_wrap__ are all called as expected, however, when using the symbolic operator (e.g. arr1-arr2) only __array_finalize__ is called. As a consequence, I lose any information stored in arr._optinfo when a mathematical operator is used.
Here is a code snippet that illustrates the issue.
#!/bin/env python
import numpy as np
from numpy.ma import MaskedArray, nomask
class InfoArray(MaskedArray):
def __new__(cls, info=None, data=None, mask=nomask, dtype=None,
copy=False, subok=True, ndmin=0, fill_value=None,
keep_mask=True, hard_mask=None, shrink=True, **kwargs):
obj = super(InfoArray, cls).__new__(cls, data=data, mask=mask,
dtype=dtype, copy=copy, subok=subok, ndmin=ndmin,
fill_value=fill_value, hard_mask=hard_mask,
shrink=shrink, **kwargs)
obj._optinfo['info'] = info
return obj
def __array_prepare__(self, out, context=None):
print '__array_prepare__'
return super(InfoArray, self).__array_prepare__(out, context)
def __array_wrap__(self, out, context=None):
print '__array_wrap__'
return super(InfoArray, self).__array_wrap__(out, context)
def __array_finalize__(self, obj):
print '__array_finalize__'
return super(InfoArray, self).__array_finalize__(obj)
if __name__ == "__main__":
arr1 = InfoArray('test', data=[1,2,3,4,5,6])
arr2 = InfoArray(data=[0,1,2,3,4,5])
diff1 = np.subtract(arr1, arr2)
print diff1._optinfo
diff2 = arr1-arr2
print diff2._optinfo
If run, the output looks like this:
$ python test_ma_sub.py
#Call to np.subtract(arr1, arr2) here
__array_finalize__
__array_finalize__
__array_prepare__
__array_finalize__
__array_wrap__
__array_finalize__
{'info': 'test'}
#Executing arr1-arr2 here
__array_finalize__
{}
Currently I have simply downgraded to 1.9.2 to solve the problem for myself, but have been having difficulty figuring out where the difference lies between 1.9.2 and 1.10.0.
Thanks,
Jeremy