Python for 循环 numpy 向量化

问题描述 投票:0回答:1

您对如何加快下面代码中的“f_img_update”功能有什么建议吗?我尝试添加 numba @jit 装饰器,但没有运气。我想 numpy 矢量化可能会起作用,但我受的教育还不够,无法让它自己工作:/

代码:

import numpy as np
import time
import random
from random import randrange


dimensions = (100, 50)  # [m]
resolution = 5  # [cm] 1,2,4,5,10,20,25,50,100
pix_res = int(100 / resolution)

height = dimensions[0] * pix_res
width = dimensions[1] * pix_res
img_size = (height, width)

# Make "RGBA" image
img = np.zeros((*img_size, 4), np.uint16)

# DATA PREPARATION
xmin = 1700000
ymin = 1400000
zmin = 100

xmax = xmin + dimensions[0]
ymax = ymin + dimensions[1]
zmax = 150

data = []
for i in range(100000):
    xyzi = [random.uniform(xmin, xmax), random.uniform(ymin, ymax), random.uniform(zmin, zmax), randrange(255)]
    data.append(xyzi)

# IMAGE UPDATE
def f_img_update(f_img, f_xmin, f_ymin, f_data, f_pix_per_1m):  # IMAGE UPDATE
    for f_xyzi in f_data:
        f_x_img, f_y_img = f_xyzi[0:2]
        f_x_img = int((f_x_img - f_xmin) * 100 / f_pix_per_1m)
        f_y_img = int((f_y_img - f_ymin) * 100 / f_pix_per_1m)
        f_img[f_x_img][f_y_img] = f_xyzi
    return f_img


t1 = time.time()
img = f_img_update(img, xmin, ymin, data, pix_res)
t2 = time.time()
print("image update time: ", t2 - t1)
python numpy vectorization
1个回答
0
投票

最简单的方法是将

data
从标准 python 列表转换为
np.array
,然后使用
@njit
装饰器:

import random
import time
from random import randrange

import numpy as np
from numba import njit

dimensions = (100, 50)  # [m]
resolution = 5  # [cm] 1,2,4,5,10,20,25,50,100
pix_res = int(100 / resolution)

height = dimensions[0] * pix_res
width = dimensions[1] * pix_res
img_size = (height, width)

# Make "RGBA" image
img = np.zeros((*img_size, 4), np.uint16)

# DATA PREPARATION
xmin = 1700000
ymin = 1400000
zmin = 100

xmax = xmin + dimensions[0]
ymax = ymin + dimensions[1]
zmax = 150

data = []
for i in range(100_000):
    xyzi = [
        random.uniform(xmin, xmax),
        random.uniform(ymin, ymax),
        random.uniform(zmin, zmax),
        randrange(255),
    ]
    data.append(xyzi)

data = np.array(data)


# IMAGE UPDATE
def f_img_update(f_img, f_xmin, f_ymin, f_data, f_pix_per_1m):  # IMAGE UPDATE
    for f_xyzi in f_data:
        f_x_img = f_xyzi[0]
        f_y_img = f_xyzi[1]
        f_x_img = int((f_x_img - f_xmin) * 100 / f_pix_per_1m)
        f_y_img = int((f_y_img - f_ymin) * 100 / f_pix_per_1m)
        f_img[f_x_img, f_y_img] = f_xyzi
    return f_img


@njit
def f_img_update_numba(f_img, f_xmin, f_ymin, f_data, f_pix_per_1m):  # IMAGE UPDATE
    for f_xyzi in f_data:
        f_x_img = f_xyzi[0]
        f_y_img = f_xyzi[1]
        f_x_img = int((f_x_img - f_xmin) * 100 / f_pix_per_1m)
        f_y_img = int((f_y_img - f_ymin) * 100 / f_pix_per_1m)
        f_img[f_x_img, f_y_img] = f_xyzi
    return f_img


# compile it first
assert np.allclose(
    f_img_update(img, xmin, ymin, data, pix_res),
    f_img_update_numba(img, xmin, ymin, data, pix_res),
)

img_copy = img.copy()
t1 = time.time()
_ = f_img_update(img_copy, xmin, ymin, data, pix_res)
t2 = time.time()
print("image update normal: ", t2 - t1)

img_copy = img.copy()
t1 = time.time()
_ = f_img_update_numba(img_copy, xmin, ymin, data, pix_res)
t2 = time.time()
print("image update time numba: ", t2 - t1)

在我的 AMD 5700x 上打印:

image update normal:  0.07558226585388184
image update time numba:  0.001255035400390625
© www.soinside.com 2019 - 2024. All rights reserved.