如何在不存储重复值的情况下使用最近邻居对numpy数组进行升采样?

时间:2019-04-01 19:08:35

标签: python numpy

比方说,我有一个3x3的数组a,并希望通过最近邻插值将其上采样到30x30的数组b

是否可以使用实际上不存储重复值的技术? broadcastingnumpy中的工作方式类似。

例如我想要一个对象,当我用b[x, x]调用0 < x < 10时得到a[0, 0]

2 个答案:

答案 0 :(得分:1)

我不相信有任何方法可以使用numpy来做到这一点。在numpy中广播的工作方式是每个轴都有一个“跨度”参数,该参数控制如何计算沿轴的下一个元素。例如:

In [1]: a = np.arange(10)

In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [3]: b = a[::2]

In [4]: b
Out[4]: array([0, 2, 4, 6, 8])

In [5]: b.strides
Out[5]: (16,)

In [6]: a.strides
Out[6]: (8,)

在这种情况下,您可以看到b只是通过沿第一维将步幅加倍获得的a的视图。因此,当您访问b[1]时,偏移量将计算为b.__array_interface__['data'][0] + b.strides[0]

在您的情况下,您实质上需要一个非线性的跨步,这是不受支持的。

您当然可以通过自己计算索引来实现这一点,即:

a[x//10,x//10]

答案 1 :(得分:1)

通过创建一个包装numpy数组并实现自定义__getitem__方法的类,可以实现与您描述的对象类似的对象。可能类似于以下内容,其中factor是您要上采样的因素。

class UpSampled:
    __slots__ = ('arr', 'factor')

    def __init__(self, arr, factor):
        self.arr = arr
        self.factor = factor

    def __getitem__(self, key):
        return self.arr[key // self.factor]

然后您将使用它,如下所示:

o = UpSampled(np.array([
    UpSampled(np.array([0, 1, 2]), 10),
    UpSampled(np.array([3, 4, 5]), 10),
    UpSampled(np.array([6, 7, 8]), 10),
]), 10)

print(o[23][13])  # prints 7

如果您需要对象是可迭代的,则还可以实现__next____iter__

class UpSampled:
    __slots__ = ('arr', 'factor', '__index')

    def __init__(self, arr, factor):
        self.arr = arr
        self.factor = factor
        self.__index = 0

    def __getitem__(self, key):
        return self.arr[key // self.factor]

    def __iter__(self):
        self.__index = 0
        return self

    def __next__(self):
        try:
            result = self[self.__index]
        except IndexError:
            raise StopIteration
        self.__index += 1
        return result

尽管我不确定这是否特别适合期望numpy数组的库。