簡體   English   中英

np.shuffle比np.random.choice慢得多

[英]np.shuffle much slower than np.random.choice

我有一個形狀數組(N,3),我想隨機地隨機排列行。 N約為100,000。

我發現np.random.shuffle阻礙了我的應用程序。 我嘗試通過調用np.random.choice代替隨機播放,並經歷了10倍的加速。 這里發生了什么? 為什么調用np.random.choice這么快? np.random.choice版本是否生成均勻分布的隨機播放?

import timeit

task_choice = '''
N = 100000
x = np.zeros((N, 3))
inds = np.random.choice(N, N, replace=False)
x[np.arange(N), :] = x[inds, :]
'''

task_shuffle = '''
N = 100000
x = np.zeros((N, 3))
np.random.shuffle(x)
'''

task_permute = '''
N = 100000
x = np.zeros((N, 3))
x = np.random.permutation(x)
'''

setup = 'import numpy as np'

timeit.timeit(task_choice, setup=setup, number=10)
>>> 0.11108078400138766

timeit.timeit(task_shuffle, setup=setup, number=10)
>>> 1.0411593900062144

timeit.timeit(task_permute, setup=setup, number=10)
>>> 1.1140159380011028

編輯:對於任何好奇的人,我決定采用以下解決方案,因為它易於讀取並且優於基准測試中的所有其他方法:

task_ind_permute = '''
N = 100000
x = np.zeros((N, 3))
inds = np.random.permutation(N)
x[np.arange(N), :] = x[inds, :]
'''

你在這里比較非常不同大小的數組。 在第一個示例中,盡管您創建了一個零數組,但您僅使用random.choice(100000, 100000) ,即可在1-100000之間提取100000個隨機值。 在第二個示例中,您將改組(100000, 3)形狀數組。

>>> x.shape
(100000, 3)
>>> np.random.choice(N, N, replace=False).shape
(100000,)

更多等效樣本的時間:

In [979]: %timeit np.random.choice(N, N, replace=False)
2.6 ms ± 201 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [980]: x = np.arange(100000)

In [981]: %timeit np.random.shuffle(x)
2.29 ms ± 67.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [982]: x.shape == np.random.choice(N, N, replace=False).shape
Out[982]: True

permutationshuffle是鏈接在一起的,實際上permutationpermutation稱為shuffle !!

shuffle比多維數組的permutation慢的原因是, permutation僅需要沿第一個軸shuffle permutation索引。 因此成為1d數組(第一個if-else塊)的shuffle的特例。

源代碼中也解釋了這種特殊情況:

# We trick gcc into providing a specialized implementation for
# the most common case, yielding a ~33% performance improvement.
# Note that apparently, only one branch can ever be specialized.

另一方面,對於shuffle ,多維ndarray操作需要反彈緩沖區,因此創建緩沖區特別是在維數相對較大時尤其昂貴。 此外,我們將無法再使用上述有助於1d情況的技巧。

使用replace=False並使用choice生成相同大小的新數組時, choicepermutation相同,請參見此處 多余的時間必須來自創建中間索引數組所花費的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM