Python惰性评估numpy ndarray [英] Python lazy evaluation numpy ndarray

查看:85
本文介绍了Python惰性评估numpy ndarray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大型2D数组,我想声明一次,并且根据参数仅偶尔更改 some 个值,而无需遍历整个数组.

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.

要构建此数组,我用dtype=object子类化了numpy ndarray类,并将其分配给我想更改功能的元素,例如:

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**2

for i in range(np.shape(A)[0]):
    A[i,i]=f
    for j in range(np.shape(A)[0]):
        A[i,j]=1.

然后我重写了__getitem__方法,以便它可以调用具有给定参数的函数的求值,否则返回值本身.

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

其中self.args先前已提供给myclass实例.

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

但是,我需要在最后使用浮点数组,并且我不能使用这种技术简单地将此数组转换为dtype=float数组.我还尝试使用numpy视图,这对于dtype=object都不起作用.

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.

您有更好的选择吗?我应该重写view方法而不是getitem吗?

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

编辑,将来我可能不得不使用Cython,因此,如果您有涉及以下方面的解决方案, C指针,我很感兴趣.

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.

推荐答案

在这种情况下,将转换函数绑定到数组的每个索引都没有意义.

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

可以如下使用:

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)

打印,

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.]])

这样,您可以轻松支持所有高级Numpy索引(按元素访问,切片,奇特索引等),同时将数据保留在具有本机数据类型(float等),这比使用dtype='object'更为有效.

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

这篇关于Python惰性评估numpy ndarray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆