【问题标题】:Indexing a NumPy array like a dictionary像字典一样索引 NumPy 数组
【发布时间】:2018-11-21 20:43:20
【问题描述】:

出于性能原因,我需要使用二维 NumPy 数组,但我还需要能够索引每个元素。索引将是models1models2,它们是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],因为不支持切片(不是说它们有意义,但是我怎样才能批量分配到第二维?我应该首先传递什么索引?),就是这样。也不支持过滤...

【问题讨论】:

  • 你能用 Pandas 代替从头开始吗?您不妨在他们的源代码中找到有用的资源。
  • @Arius 我一开始实际上使用了DataFrame,但因为性能至关重要,所以放弃了它,转而使用 NumPy。
  • 你为什么不继承np.ndarray。这里有解释:docs.scipy.org/doc/numpy-1.13.0/user/basics.subclassing.html。然后你可以重载__new____setitem____getitem__
  • 我知道模仿字典的唯一方法是使用structured array,但这只允许使用字符串作为索引,所以@FHTMitchell 的想法可能是最好的。
  • m1m2 是什么?具有整数(或列表、数组或切片)值的变量?还是弦乐?还是更复杂的可散列值?如何设置一个字典或函数将这些值映射到ndarray 可以使用的简单索引?

标签: python arrays python-2.7 numpy


【解决方案1】:

如果我理解得很好,您希望能够在字典modelX_indices 中为模型提供键以及它们的索引?

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

  • 如果 key 参数是一个元组或列表,我们会将其中的每个条目视为一个单独的键,以将其转换为 int。
  • 如果键是切片,我们不会触摸它*。
  • 如果键是 Model,我们将其转换为 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

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

【讨论】:

  • 你会如何使用key_to_int?您建议我根本不应该 sublcas,只需使用常规的 np.ndarray 并且每次访问它时都需要将 models1models2 映射到 int?
  • 不,key_to_int 是您已编写的类的属性。事实上你可以把代码放在你的__setitem____getitem__中,但是会有重复的代码,这就是我写一个函数的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 2015-12-16
  • 2018-10-25
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
相关资源
最近更新 更多