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

esyap4oy  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(84)

我想从一个图像中随机 Shuffle 的像素。与以下功能一切都像我想要的工作,但它是缓慢的。

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是<class 'generator'>,没有像第一个函数那样的numpy数组。有没有办法使用第二个函数并将结果转换为数组?
thx

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

8oomwypt

8oomwypt1#

听起来你最终是在寻找第一个函数的更快版本;我假设用yield将函数转换成Python生成器是没有必要的,你只是在寻找更快的替代品。(注意,它看起来更快只是因为它没有做所有的工作。)
你是对的,生成一个置换索引数组并使用它们来 Shuffle 图像往往比使用shuffle更快。

import numpy as np

def randomize_image(img):
    # convert image from (m,n,3) to (N,3)
    # Note "-1" means "whatever size is necessary"
    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))


在某些情况下,还有其他几种可能性可以更快,例如沿着最后一个轴(在内存中是连续的,假设你的图像是一个行优先数组)工作,并使用np.argsort(rng.random(size=N))来生成排列,但它们似乎并不快。

相关问题