我需要創建一個長度爲n
的NumPy數組,其中每個元素是v
。NumPy數組初始化(填充相同的值)
有什麼優於:
a = empty(n)
for i in range(n):
a[i] = v
我知道zeros
和ones
會爲V = 0,1,我可以用v * ones(n)
工作,但是當v
是None
它不會工作,並且也將慢得多。
我需要創建一個長度爲n
的NumPy數組,其中每個元素是v
。NumPy數組初始化(填充相同的值)
有什麼優於:
a = empty(n)
for i in range(n):
a[i] = v
我知道zeros
和ones
會爲V = 0,1,我可以用v * ones(n)
工作,但是當v
是None
它不會工作,並且也將慢得多。
NumPy的1.8引入np.full()
,這比empty()
更直接的方法,接着fill()
用於創建填充有一定值的數組:
>>> np.full((3, 5), 7)
array([[ 7., 7., 7., 7., 7.],
[ 7., 7., 7., 7., 7.],
[ 7., 7., 7., 7., 7.]])
>>> np.full((3, 5), 7, dtype=int)
array([[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7]])
這無疑是創建填充有陣列的方式某些值,因爲它明確地描述了要實現的目標(原則上它可以非常有效,因爲它執行一個非常具體的任務)。
這個full()方法對我來說很好,但我找不到一點文檔。任何人都可以將我指向正確的地方嗎? – 2014-01-17 16:39:07
您至少可以在Python shell中執行'help(numpy.full)'。我也很驚訝它不在網絡文檔中。 – EOL 2014-01-22 13:49:26
在我的系統上(Python 2.7,Numpy 1.8),np.full()實際上比np.empty()跟np.fill()稍慢。 – 2014-07-25 08:37:06
我相信fill
是做到這一點的最快方法。
a = np.empty(10)
a.fill(7)
你應該總是避免迭代,就像你在你的例子中做的那樣。一個簡單的a[:] = v
將完成你的迭代使用numpy broadcasting。
您可以使用numpy.tile
,例如, :
v = 7
rows = 3
cols = 5
a = numpy.tile(v, (rows,cols))
a
Out[1]:
array([[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7],
[7, 7, 7, 7, 7]])
雖然tile
意指「瓦片」的陣列(而不是標量,如在這種情況下),它會做的工作,在創建任何大小和尺寸的預填充陣列。
更新了numpy的1.7.0:(HAT-尖端@Rolf Bartstra。)
a=np.empty(n); a.fill(5)
是最快的。
在下降速度順序:
%timeit a=np.empty(1e4); a.fill(5)
100000 loops, best of 3: 5.85 us per loop
%timeit a=np.empty(1e4); a[:]=5
100000 loops, best of 3: 7.15 us per loop
%timeit a=np.ones(1e4)*5
10000 loops, best of 3: 22.9 us per loop
%timeit a=np.repeat(5,(1e4))
10000 loops, best of 3: 81.7 us per loop
%timeit a=np.tile(5,[1e4])
10000 loops, best of 3: 82.9 us per loop
添加更新和直接'np.full()'的時間將是有用的。在我的機器上,使用NumPy 1.8.1,它比不太直接的'fill()'版本慢了大約15%(這是意想不到的,因爲full()有可能會稍微快一點)。 – EOL 2014-05-14 06:44:09
@DavidSanders:我不確定我在跟着你:'fill()'是最快的解決方案。乘法解決方案要慢得多。 – EOL 2015-06-23 03:22:49
注意:如果速度真的是一個問題,使用'10000'而不是'1e4'的大小會產生明顯的差異,出於某種原因('full()'比'1e4'慢50%)。 – EOL 2015-06-23 03:27:19
顯然,不僅絕對速度,而且速度順序(如由user1579844報告的)是依賴於機器;這裏是我發現的:
a=np.empty(1e4); a.fill(5)
是最快的;
在下降速度順序:
timeit a=np.empty(1e4); a.fill(5)
# 100000 loops, best of 3: 10.2 us per loop
timeit a=np.empty(1e4); a[:]=5
# 100000 loops, best of 3: 16.9 us per loop
timeit a=np.ones(1e4)*5
# 100000 loops, best of 3: 32.2 us per loop
timeit a=np.tile(5,[1e4])
# 10000 loops, best of 3: 90.9 us per loop
timeit a=np.repeat(5,(1e4))
# 10000 loops, best of 3: 98.3 us per loop
timeit a=np.array([5]*int(1e4))
# 1000 loops, best of 3: 1.69 ms per loop (slowest BY FAR!)
所以,儘量找出來,用什麼速度最快的平臺上。
我腦子裏
numpy.array(n * [value])
,但顯然這是比所有其他的建議較慢足夠大n
。
這裏是與perfplot(我的一個寵物項目)的完整比較。
兩個empty
替代品仍然是最快的(與NumPy的1.12.1)。 full
迎頭趕上大型陣列。
代碼,以生成劇情:
import numpy as np
import perfplot
def empty_fill(n):
a = np.empty(n)
a.fill(3.14)
return a
def empty_colon(n):
a = np.empty(n)
a[:] = 3.14
return a
def ones_times(n):
return 3.14 * np.ones(n)
def repeat(n):
return np.repeat(3.14, (n))
def tile(n):
return np.repeat(3.14, [n])
def full(n):
return np.full((n), 3.14)
def list_to_array(n):
return np.array(n * [3.14])
perfplot.show(
setup=lambda n: n,
kernels=[
empty_fill, empty_colon, ones_times, repeat, tile, full, list_to_array
],
n_range=[2**k for k in range(23)],
xlabel='len(a)',
logx=True,
logy=True,
)
在我的電腦,對於0的情況下,使用一個'= np.zeros(n)的'在環路是比'更快。填充(0)'。這與我所期望的相反,因爲我認爲'a = np.zeros(n)'需要分配和初始化新的內存。如果有人能解釋這一點,我將不勝感激。 – user3731622 2016-09-27 23:40:03