代码之家  ›  专栏  ›  技术社区  ›  dabadaba

像字典一样索引numpy数组

  •  2
  • dabadaba  · 技术社区  · 8 年前

    出于性能原因,我需要使用二维numpy数组,但也需要能够为每个元素编制索引。指数将是 models1 和 models2 哪一个子类 django.db.models.Model .

    我需要能够获取和设置项、切片和传递索引列表、过滤器等等,就像它是一个有整数索引的常规numpy一样。但我也需要能够做到这一点使用提到的指数。

    我应该能够做的操作示例:

    arr[m1]
    arr[:,m2]
    arr[(0,1,4),:] = N
    

    有没有一种标准化的方法来索引numpy数组?我还没找到。

    我试过这个:

    class IndexedArray:
        def __init__(self, models1, models2):
            self.shape = (len(models1), len(models2))
            self.arr = np.full(self.shape, 1)
            self.models1 = [m1 for m1 in models1]
            self.models2 = [m2 for m2 in models2]
            self.model1_indices = {m1: i for i, m1 in enumerate(self.models1)}
            self.model2_indices = {m2: i for i, m2 in enumerate(self.models2)}
    
        def __setitem__(self, key, value):
            if isinstance(key, tuple):
                i = self.models1_indices[key[0]]
                j = self.models2_indices[key[1]]
                self.arr[i, j] = value
            else:
                i = self.models1_indices[key]
                self.arr[i] = value
    
        def __getitem__(self, key):
            if isinstance(key, tuple):
                i = self.models1_indices[key[0]]
                j = self.models2_indices[key[1]]
                return self.arr[i, j]
            i = self.models1_indices[key]
            return self.arr[i]
    
        def get_index(self, o):
            if isinstance(o, Model1):
                return self.models1_indices[o]
            if isinstance(o, Model2):
                return self.models2_indices[o]
            raise TypeError
    

    但可用的操作数量有限。我只能得到和设置 arr[m1,m2] , arr[m1] 但不是 arr[:,m2] 因为切片是不受支持的(这不是说它们有意义,但是我怎样才能将质量分配给第二个维度呢?我应该通过什么作为第一个索引?),就这样。也不支持筛选…

    1 回复  |  直到 8 年前
        1
  •  2
  •   Morgan Leclerc    8 年前

    如果我理解的好的话,你可以给模型的键以及它们的索引 modelX_indices ?

    这就是我解决问题的方法:

    • 如果key参数是元组或列表,我们将内部的每个条目作为单独的键来将其转换为int。
    • 如果钥匙是一片,我们就不要碰它。
    • 如果键是模型,则将其转换为int,如果它已经是int,则不要触摸它。

    以下函数可执行此操作:

    def key_to_int(self, key):
        if isinstance(key, (tuple, list)):
            return tuple(key_to_int(k) for k in key)
        if isinstance(key, Model1):
            return self.models1_indices[key]
        if isinstance(key, Model2):
            return self.models2_indices[key]
        return key
    

    *:除非你对模型有感觉?