如何将 <class 'generator'> 转换为 numpy 数组

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

我想以随机方式从图像中打乱像素。通过以下功能,一切都按照我想要的方式工作,但速度很慢。

def randomize_image(img):
    # convert image from (m,n,3) to (N,3)
    rndImg = np.reshape(img, (img.shape[0]*img.shape[1], img.shape[2]))
    
    start_time = time.perf_counter()
    np.random.shuffle(rndImg)
    end_time = time.perf_counter()
    print('Time random shuffle: ', end_time - start_time)     
    
    rndImg = np.reshape(rndImg, img.shape)
    return rndImg

这就是为什么我将其更改为下一个功能。它也正在工作,dtype 是 并且没有像第一个函数中那样的 numpy 数组。 有没有办法使用第二个函数并将结果转换为数组?

谢谢

def rand_shuffle_faster(img):
    # convert image from (m,n,3) to (N,3)
    rndImg = np.reshape(img, (img.shape[0]*img.shape[1], img.shape[2]))
    length = rndImg.shape[1]
    yield rndImg[:, np.random.permutation(length)]
    rndImg = np.reshape(rndImg, img.shape)
    return rndImg
python numpy generator
1个回答
0
投票

听起来您最终想要的是第一个函数的更快版本;我认为将函数转换为带有

yield
的 Python 生成器是没有必要的,您这样做只是为了寻找更快的替代方案。 (请注意,它看起来更快只是因为它没有完成所有工作。)

你是对的,生成索引的排列数组并使用它们来洗牌图像往往比使用

shuffle
更快。

import numpy as np

def randomize_image(img):
    # convert image from (m,n,3) to (N,3)
    rndImg = np.reshape(img, (-1, img.shape[2]))
    np.random.shuffle(rndImg)    
    rndImg = np.reshape(rndImg, img.shape)
    return rndImg

def randomize_image2(img):
    # convert image from (m,n,3) to (N,3)
    rndImg = np.reshape(img, (-1, img.shape[2]))
    i = np.random.permutation(len(rndImg))
    rndImg = rndImg[i, :]
    rndImg = np.reshape(rndImg, img.shape)
    return rndImg

m, n = 1000, 1000
img = np.arange(m*n*3).reshape(m, n, 3)

img1 = randomize_image(img)
%timeit randomize_image1(img)
# 1.69 s ± 505 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

img2 = randomize_image2(img)
%timeit randomize_image2(img)
# 152 ms ± 31.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

根据图像的大小,使用 NumPy Generator 执行排列(而不是

np.random.permutation
)可能会更快。

# include this outside of the function
rng = np.random.default_rng()
...
# inside the function, replace 
# i = np.random.permutation(len(rndImg)
# with:
i = rng.permutation(len(rndImg))
© www.soinside.com 2019 - 2024. All rights reserved.