Numpy:如何使用数组的最后一个维度作为值?
Posted
技术标签:
【中文标题】Numpy:如何使用数组的最后一个维度作为值?【英文标题】:Numpy: How can I use last dimension of an array as a value? 【发布时间】:2022-01-20 03:58:58 【问题描述】:我有一个形状为[1080, 1920, 4]
的 3-D 数组,最后一个轴代表图片的 RGBA 通道,我有一个从 RGBA 值到 int 的 dict 映射,我想使用 np.vectorize
来转换这个数组到形状为[1080, 1920]
的二维数组,如何将数组作为二维数组传递,最后一维是向量化函数的列表?
array = [[[112, 25, 235, 255],
[112, 25, 235, 255],
[112, 25, 235, 255],
...,
[ 35, 35, 30, 255],
[ 41, 40, 37, 255],
[ 39, 41, 37, 255]]
...,
[ 35, 35, 30, 255],
[ 41, 40, 37, 255],
[ 39, 41, 37, 255]]]
dic = (35, 35, 30, 255): 1, (41, 40, 37, 255): 2
np.vectorize(lambda x: dic.get(tuple(x)))()
我应该将什么传递给最后一个()
【问题讨论】:
你的意思是需要将3D列表扁平化成2D列表,对吧,然后传入函数中,对吧?np.vectorize
是一个美化的for
循环。您对其他方法持开放态度吗?
听起来像array.reshape(-1, 4)
。
【参考方案1】:
一种使用numpy.apply_along_axis
的方式:
# Data with (3, 3, 4)
array([[[112, 25, 235, 255],
[112, 25, 235, 255],
[112, 25, 235, 255]],
[[ 35, 35, 30, 255],
[ 41, 40, 37, 255],
[ 39, 41, 37, 255]],
[[ 35, 35, 30, 255],
[ 41, 40, 37, 255],
[ 39, 41, 37, 255]]])
dic = (112, 25, 235, 255): 0,
(35, 35, 30, 255): 1,
(41, 40, 37, 255): 2,
(39, 41, 37, 255): 3
np.apply_along_axis(lambda x: dic.get(tuple(x)), 2, array)
输出:
array([[0, 0, 0],
[1, 2, 3],
[1, 2, 3]])
【讨论】:
numpy.apply_along_axis
确实有效,但似乎很慢,但感谢您的帮助【参考方案2】:
vectorize
通常将标量值传递给函数。但是你可以指定一个signature
:
In [55]: f=np.vectorize(lambda x: dic.get(tuple(x)),signature='(n)->()')
使用@Chris 示例值:
In [56]: f(arr)
Out[56]:
array([[0, 0, 0],
[1, 2, 3],
[1, 2, 3]])
但vectorize
警告signature
使用速度较慢:
In [57]: timeit f(arr)
178 µs ± 6.38 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
像@Chris 那样使用apply...
:
In [58]: timeit np.apply_along_axis(lambda x: dic.get(tuple(x)),2, arr)
131 µs ± 1.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
以及对“扁平化”数组的列表理解:
In [59]: timeit np.array([dic.get(tuple(x)) for x in arr.reshape(-1,4)]).reshape(ar
...: r.shape[:2])
35.3 µs ± 108 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
vectorize
的速度劣势随着更大的数组而消失,尽管我不知道这是否适用于signature
的情况。
【讨论】:
以上是关于Numpy:如何使用数组的最后一个维度作为值?的主要内容,如果未能解决你的问题,请参考以下文章