Python lazy evaluation numpy ndarray
In this case, it does not make sens to bind a transformation function, to every index of your array.
Instead, a more efficient approach would be to define a transformation, as a function, together with a subset of the array it applies to. Here is a basic implementation,
import numpy as npclass LazyEvaluation(object): def __init__(self): self.transforms = [] def add_transform(self, function, selection=slice(None), args={}): self.transforms.append( (function, selection, args)) def __call__(self, x): y = x.copy() for function, selection, args in self.transforms: y[selection] = function(y[selection], **args) return y
that can be used as follows:
x = np.ones((6, 6))*2le = LazyEvaluation()le.add_transform(lambda x: 0, [[3], [0]]) # equivalent to x[3,0]le.add_transform(lambda x: x**2, (slice(4), slice(4,6))) # equivalent to x[4,4:6]le.add_transform(lambda x: -1, np.diag_indices(x.shape[0], x.ndim), ) # setting the diagonal result = le(x)print(result)
which prints,
array([[-1., 2., 2., 2., 4., 4.], [ 2., -1., 2., 2., 4., 4.], [ 2., 2., -1., 2., 4., 4.], [ 0., 2., 2., -1., 4., 4.], [ 2., 2., 2., 2., -1., 2.], [ 2., 2., 2., 2., 2., -1.]])
This way you can easily support all advanced Numpy indexing (element by element access, slicing, fancy indexing etc.), while at the same time keeping your data in an array with a native data type (float
, int
, etc) which is much more efficient than using dtype='object'
.