En este caso, no tiene sentido vincular una función de
transformación a cada índice de su matriz.
En cambio, un enfoque más eficiente sería definir una
transformación, como una función, junto con un subconjunto de la
matriz a la que se aplica. Aquí hay una implementación básica,
import numpy as np
class 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
que se puede usar de la siguiente manera:
x = np.ones((6, 6))*2
le = 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)
que imprime,
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.]])
De esta forma, puede admitir fácilmente todos los índices Numpy
avanzados (elemento por acceso a los elementos, segmentación,
indexación sofisticada, etc.), mientras que al mismo tiempo
mantiene sus datos en una matriz con un tipo de datos nativo (
float
, int
, etc.) que es mucho más
eficiente que usar dtype = 'object'
.