Python numpy数组序列化和映射的有效方法
假设我们有一个2d数组(例如深度图像)。我正在寻找一种有效的方法来序列化这个数组并应用函数Python numpy数组序列化和映射的有效方法,python,arrays,numpy,Python,Arrays,Numpy,假设我们有一个2d数组(例如深度图像)。我正在寻找一种有效的方法来序列化这个数组并应用函数 数组是一个高度x宽度2d数组 序列化array-->在范围(0,宽度)和范围(0,高度)中的x和y的所有组合的[x,y,array[y,x]]列表 应用函数func:func(x,y,数组[y,x]) 示例代码: import numpy as np import itertools width,height= 640,480 xstep,ystep= 1,1 array= np.array([np.sq
数组
是一个高度
x宽度
2d数组array
-->在范围(0,宽度)
和范围(0,高度)
中的x
和y
的所有组合的[x,y,array[y,x]]
列表func
:func(x,y,数组[y,x])
import numpy as np
import itertools
width,height= 640,480
xstep,ystep= 1,1
array= np.array([np.sqrt(x*x+y*y) for y,x in itertools.product(range(0,height,ystep), range(0,width,xstep))]).reshape(height,width)
func= lambda x,y,z: [np.sqrt(x),np.sqrt(y),np.sqrt(x*x+y*y+z*z)]
我尝试了几种方法:
%%time
points1= [func(x,y,array[y,x]) for y,x in itertools.product(range(0,height,ystep), range(0,width,xstep))]
#--> Wall time: 1.15 s
有比这些更快的解决方案吗?问题是,您正在计算单个元素的平方根,而没有利用矢量化。您可以用数组操作替换
func
:
def compute(array):
indices = np.indices(array.shape)
merged = np.empty((*array.shape, 3))
merged[:,:,0] = np.sqrt(indices[1])
merged[:,:,1] = np.sqrt(indices[0])
merged[:,:,2] = np.sqrt(np.square(indices[1]) + np.square(indices[0]) + np.square(array))
return merged.reshape((-1, 3)).tolist()
merged
是一个三维数组,包含func(x,y,数组[y,x])
中的值merged[y,x,:]
。此外,通过将此数组重新调整为x*y乘以3的数组,可以方便地将其转换为列表
事实上,func
已经矢量化了。您只需要将数组而不是单个元素传递给它。但是,它可以利用使用np.square
:
func=lambda x,y,z:[np.sqrt(x),np.sqrt(y),np.sqrt(np.square(x)+np.square(y)+np.square(z))]
经过这些修改后,创建列表的速度比以前快15倍左右:
def计算(数组):
索引=np.索引(数组.形状)
merged=np.dstack(func(索引[1],索引[0],数组))
return merged.reforme(-1,3)).tolist()
列表1=[func(x,y,数组[y,x])表示itertools.product中的y,x(范围(0,高度,ystep),范围(0,宽度,xstep))]
list2=[func(x,y,数组[y,x]),用于np.ndindex(array.shape)中的y,x]
列表3=[func(x,y,value)表示(y,x),np.ndenumerate(数组)中的值]
list4=计算(数组)
断言(list1==list2和list1==list3和list1==list4)
timeit.timeit(lambda:[func(x,y,数组[y,x]),用于itertools.product中的y,x(范围(0,高度,ystep),范围(0,宽度,xstep)),数字=1)
# 1.2148581651999848
timeit.timeit(lambda:[func(x,y,数组[y,x]),用于np.ndindex(array.shape)]中的y,x,数字=1)
# 1.3134885265999856
timeit.timeit(lambda:[func(x,y,value)表示(y,x),np.ndenumerate(数组)中的值],数字=1)
# 1.2504884549999815
timeit.timeit(lambda:compute(数组),number=1)
# 0.0784944145899999
我想您正在寻找。在检查它之后,它是in-numpy的一种替代方法。ndenumerate实际上运行得有点慢,而且
%%time
points3= [func(x,y,array[y,x]) for y,x in np.array(np.meshgrid(range(0,height,ystep),range(0,width,xstep))).T.reshape(-1,2)]
#--> Wall time: 2.16 s
points1==points2, points1==points3
#--> (True, True)
def compute(array):
indices = np.indices(array.shape)
merged = np.empty((*array.shape, 3))
merged[:,:,0] = np.sqrt(indices[1])
merged[:,:,1] = np.sqrt(indices[0])
merged[:,:,2] = np.sqrt(np.square(indices[1]) + np.square(indices[0]) + np.square(array))
return merged.reshape((-1, 3)).tolist()