Python lazy evaluation numpy ndarray

2024/10/11 10:25:35

I have a large 2D array that I would like to declare once, and change occasionnaly only some values depending on a parameter, without traversing the whole array.

To build this array, I have subclassed the numpy ndarray class with dtype=object and assign to the elements I want to change a function e.g. :

def f(parameter):return parameter**2for i in range(np.shape(A)[0]):A[i,i]=ffor j in range(np.shape(A)[0]):A[i,j]=1.

I have then overridden the __getitem__ method so that it returns the evaluation of the function with given parameter if it is callable, otherwise return the value itself.

    def __getitem__(self, key):value = super(numpy.ndarray, self).__getitem__(key)if callable(value):return value(*self.args)else:return value

where self.args were previously given to the instance of myclass.

However, I need to work with float arrays at the end, and I can't simply convert this array into a dtype=float array with this technique. I also tried to use numpy views, which does not work either for dtype=object.

Do you have any better alternative ? Should I override the view method rather than getitem ?

Edit I will maybe have to use Cython in the future, so if you have a solution involving e.g. C pointers, I am interested.

Answer

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'.

https://en.xdnf.cn/q/69782.html

Related Q&A

Python 2.7 NetworkX (Make it interactive)

I am new to NetworkX. Right now, I manage to connect all the nodes to this particular node. What I want to do next it to make it interactive e.g. able to make each of the node move by dragging using cu…

Normal Distribution Plot by name from pandas dataframe

I have a dataframe like below:dateTime Name DateTime day seconds zscore 11/1/2016 15:17 james 11/1/2016 15:17 Tue 55020 1.158266091 11/1/2016 13:41 james 11/1/2016 13:41 Tue 4926…

Change pyttsx3 language

When trying to use pyttsx3 I can only use English voices. I would like to be able to use Dutch as well. I have already installed the text to speech language package in the windows settings menu. But I …

pandas groupby dates and years and sum up amounts

I have pandas dataframe like this:d = {dollar_amount: [200.25, 350.00, 120.00, 400.50, 1231.25, 700.00, 350.00, 200.25, 2340.00], date: [22-01-2010,22-01-2010,23-01-2010,15-02-2010,27-02-2010,07-03-201…

Is Python on every GNU/Linux distribution?

I would like to know if is Python on every G/L distribution preinstalled or not. And why is it so popular on GNU/Linux and not so much on Windows?

Installing QuantLib in Anaconda on the Spyder Editor (Windows)

How do I install the QuantLib Package in Anaconda. I have tried the following code;import QuantLib as qlbut I am getting the following result;ModuleNotFoundError: No module named QuantLibCan anyone ass…

get rows with empty dates pandas python

it looks like this:Dates N-D unit 0 1/1/2016 Q1 UD 1 Q2 UD 2 Q3 UD 3 2/1/2016 Q4 UD 4 5/1/2016 Q5 UD 5 Q6 UDI want to filter out the empty Dates row…

Python: Gridsearch Without Machine Learning?

I want to optimize an algorithm that has several variable parametersas input.For machine learning tasks, Sklearn offers the optimization of hyperparameters with the gridsearch functionality.Is there a …

Pandas division (.div) with multiindex

I have something similar to thisdf = pd.DataFrame(np.random.randint(2, 10, size = (5, 2))) df.index = pd.MultiIndex.from_tuples([(1, A), (2, A), (4, B), (5, B), (8, B)]) df.index.names = [foo, bar] df.…

Add a delay to a specific scrapy Request

Is it possible to delay the retry of a particular scrapy Request. I have a middleware which needs to defer the request of a page until a later time. I know how to do the basic deferal (end of queue), a…