如何索引一个包裹着(嵌套的2D)numpy数组的对象?

yv5phkfx  于 2022-12-26  发布在  其他
关注(0)|答案(1)|浏览(107)

我有一个程序,我想在其中使用numpy来获得纯Python的最大效率。有两个类:

import numpy as np

class Individual:
    def __init__(self, vector: np.ndarray) -> None:
        self.value = vector
        
    def __getitem__(self, index):
        return self.value[index]

class Population:
    def __init__(self, individuals=np.array([])):
        self.individuals = individuals

    def __getitem__(self, index):
        return self.individuals[index]

ind1 = Individual(np.array([1, 2]))
ind2 = Individual(np.array([3, 4]))
population = Population(np.array([ind1, ind2]))

Population是个体的容器。所以人口看起来像np.array[individual1, individual2, individual3, ...]
我想要的是在程序中使用掩码来省略循环。例如,使用这样一个数组:

mask =  [[True, False], [False, True]]

作为population对象本身上的遮罩:

population[mask] = blblblbllb...

但是我的问题是当我的群体由Individual对象组成时,我不能使用2D切片。有什么解决方案可以使它以一种很好的方式工作并保持在这个类中吗?
我的目标是拥有让我做的功能:

population[mask] = population2[mask]

type(population[0])仍然是Individual而不是np.ndarray
我试图使Individual类似于the numpy docs中描述的自定义数组容器,并使用def __array__,但问题是,如果我创建这样的填充

pop = Population(np.array([Individual(some_array)]))

当我尝试索引时,pop[0]不再是一个Individual对象,而只是一个np.ndarray

yfjy0ee7

yfjy0ee71#

the page you linked中所述,我们可以实现__array__方法来指示numpy函数如何将对象转换为numpy数组,但试图索引对象时仍然只调用其__getitem__方法,因此我们可以将两者结合起来得到:

class Population:
    def __init__(self, individuals=np.array([])):
        self.individuals = individuals

    def __array__(self, dtype=None):
        return np.array([ind.value for ind in self.individuals])

    def __getitem__(self, index):
        return np.asarray(self).__getitem__(index)

现在这个办法行得通了:

mask = [[True, False], [False, True]]
print(population[mask])

并将给予:

[1 4]

如预期的那样。

相关问题