比方说,我有一个3x3的数组a
,并希望通过最近邻插值将其上采样到30x30的数组b
。
是否可以使用实际上不存储重复值的技术? broadcasting
在numpy
中的工作方式类似。
例如我想要一个对象,当我用b[x, x]
调用0 < x < 10
时得到a[0, 0]
。
答案 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数组的库。