我需要制作一个函数,以高分辨率接收索引向量,例如 hr
,并在以低分辨率 lr
采样时输出它们对应的索引。
我的想法是创建一个翻译矩阵如下:
在下面的矩阵中,其高分辨率为(6, 12)
,其低分辨率为(2, 4)
如果输入向量是
v = [0, 1, 4, 24, 36, 42]
我会实现我的翻译
w = m[v]
我希望输出 [0,0,1,0,4,6]
问题:
- 这是正确的做法吗?
- 如果是这样,我如何在 numpy 中创建
m
ndarray?
此外,如果这个问题有更好的名称,请告诉我,以便我进行更改。
节省空间的方式:
import numpy as np
hires = np.array((6, 12))
lowres = np.array((2,4))
h, w = hires // lowres
m = np.arange(np.prod(lowres)).reshape(lowres)
print(m)
# [[0 1 2 3]
# [4 5 6 7]]
v = [0, 1, 4, 24, 36, 42]
i, j = np.unravel_index(v, hires)
w = m[i // h, j // w]
print(w)
# [0 0 1 0 4 6]
空间效率低下的方式:
import numpy as np
hires = np.array((6, 12))
lowres = np.array((2,4))
h, w = hires // lowres
# DON'T DO THIS. INEFFICIENT
m = np.kron(np.arange(np.prod(lowres)).reshape(lowres), np.ones(h, w), )
print(m)
# [[0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [0. 0. 0. 1. 1. 1. 2. 2. 2. 3. 3. 3.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]
# [4. 4. 4. 5. 5. 5. 6. 6. 6. 7. 7. 7.]]
v = [0, 1, 4, 24, 36, 42]
w = m[np.unravel_index(v, hires)]
print(w)
# [0. 0. 1. 0. 4. 6.]
这里的主要思想是使用np.unravel_index
将“平面索引”转换为给定要索引到的数组形状的坐标元组。
例如,
In [446]: np.unravel_index([0, 1, 4, 24, 36, 42], (6, 12))
Out[446]: (array([0, 0, 0, 2, 3, 3]), array([0, 1, 4, 0, 0, 6]))
它返回两个索引数组,它们一起给出形状数组 (6, 12) 中第 0、1、4 等“扁平化”元素的坐标。
空间效率低下的方法构造了大的 m
数组,然后通过用这些坐标索引 m
来找到 w
:w = m[np.unravel_index(v, hires)]
.
更节省空间的方法只是将坐标除以 block 大小(在本例中为 3×3)以生成低分辨率坐标。这避免了生成大矩阵 m
的需要。我们可以改用更小的矩阵
In [447]: m = np.arange(np.prod(lowres)).reshape(lowres); m
Out[447]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
并对其进行索引:w = m[i//h, j//w]
。
您可能还对 np.ravel_multi_index
感兴趣,这是 np.unravel_index
的倒数:
In [451]: np.ravel_multi_index((np.array([0, 0, 0, 2, 3, 3]), np.array([0, 1, 4, 0, 0, 6])), (6, 12))
Out[451]: array([ 0, 1, 4, 24, 36, 42])
它将坐标数组i
和j
转换回v
。
我是一名优秀的程序员,十分优秀!