numpy 如何在不进行插值的情况下有效地将一维数组扩展到任意大小?

7hiiyaii  于 2023-06-06  发布在  其他
关注(0)|答案(3)|浏览(288)

我正在尝试将一维数组拉伸到任意大小而不进行插值。
例如:

>>> my_array
*[0,1,8,4]*
>>> stretch(my_array, 7)
*[0,0,1,1,8,8,4]*

>>> my_array
*[6,3,7,1]*
>>> stretch(my_array, 10)
*[6,6,3,3,3,7,7,7,1,1]*

等等的。
我天真的方法正是我想要的。

def interp(list, length):
   out = np.zeros(length, dtype=np.uint)
   for x in range(length):
        out[x] = list[int(x * (len(list)/length))]
   return out

然而,事实证明这是极其缓慢的;我试图每帧做几十/几百次。
interp方法对于连续函数很好用,但我也试图处理非连续数据。(如在实施例中)
numpy.repeat很接近,但只能将数组拉伸某个整数倍。
感谢阅读!
编辑:为了澄清,我想我正在尝试在一维中进行最近邻插值。
例如:

[ 5| 5| 7| 7| 7| 9| 9]
[  5   |   7  |   9  ]

我尝试从底部数组到顶部,对于任意大小。
目标数组的每个单元格都Map到输入数组中它最近的邻居。

qv7cva1a

qv7cva1a1#

确切的逻辑尚不清楚,但向量解决方案可能是使用numpy.repeat和切片:

my_array = np.array([0,1,8,4])

def stretch(a, n):
    return np.repeat(a, np.ceil(n/len(a)))[:n]

stretch(my_array, 7)
# array([0, 0, 1, 1, 8, 8, 4])

stretch(my_array, 10)
# array([0, 0, 0, 1, 1, 1, 8, 8, 8, 4])

您可以根据需要的规则调整切片部分

bvpmtnay

bvpmtnay2#

通过公式k * n // m创建从0n-1m索引列表,并使用隐式循环通过解引用初始列表生成新列表。
例如

[6, 3, 7, 1] -> [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3] -> [6, 6, 6, 3, 3, 3, 7, 7, 7, 1, 1]

单行线:

print([a[k * n // m] for k in range(m)])

双内衬:

i= [k * n // m for k in range(m)]
print([a[i[k]] for k in range(m)])

如果nm是常数,则只计算一次索引。我怀疑没有人能做得更好。
OpenCV的resizeINTER_NEAREST模式下就是这样做的。如果在单个图像行上完成,开销可能无法承受。如果在多行上完成,可能会更快。

jobtbby3

jobtbby33#

类似于Yves方法,但使用np.linspace生成索引。

import numpy as np

def stretch( arr, length ):
    idx = np.linspace( 0, len(arr), length, endpoint = False).astype( np.int64 )
    # endpoint = False to get the final index as len(arr) - 1
    # print( idx )
    # print( arr[idx] )
    return arr[idx]

np.random.seed( 1234 ) 
arr = np.random.randint( 0, 10, 10 )
arr
# array([3, 6, 5, 4, 8, 9, 1, 7, 9, 6])

stretch( arr, 15 )
# array([3, 3, 6, 5, 5, 4, 8, 8, 9, 1, 1, 7, 9, 9, 6])

时间

%timeit [arr[k * len(arr) // 1000000] for k in range(1000000)]
284 ms ± 3.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit stretch( arr, 1000000 )
6.37 ms ± 18.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

将10个元素拉伸到1,000,000是拉伸速度的40倍。

相关问题