這裏是你的代碼的速度稍快的版本:
def alt(a):
A = np.full((len(a), max(map(len, a))), np.nan)
for i, aa in enumerate(a):
A[i, :len(aa)] = aa
return A
的for循環是不可避免的。鑑於a
是一個Python列表,周圍有必要通過在列表中的項目進行迭代沒有得到。有時循環可以隱藏(電話背後max
和map
例如),但速度明智的,他們基本上等同於Python的循環。
下面是使用a
與最終形狀(100, 100)
基準:
In [197]: %timeit orig(a)
10000 loops, best of 3: 125 µs per loop
In [198]: %timeit alt(a)
10000 loops, best of 3: 84.1 µs per loop
In [199]: %timeit using_pandas(a)
100 loops, best of 3: 4.8 ms per loop
這是用來爲基準設置:
import numpy as np
import pandas as pd
def make_array(h, w):
a = []
for i in np.arange(h):
a += [np.random.rand(np.random.randint(1,w+1))]
a = np.array(a)
return a
def orig(a):
max_len_of_array = 0
for aa in a:
len_of_array = aa.shape[0]
if len_of_array > max_len_of_array:
max_len_of_array = len_of_array
n = a.shape[0]
A = np.zeros((n, max_len_of_array)) * np.nan
for i, aa in enumerate(zip(a)):
A[i][:aa[0].shape[0]] = aa[0]
return A
def alt(a):
A = np.full((len(a), max(map(len, a))), np.nan)
for i, aa in enumerate(a):
A[i, :len(aa)] = aa
return A
def using_pandas(a):
return pd.DataFrame.from_records(a).values
a = make_array(100,100)
你能保持max_len_of_array的'軌道'當你填寫原始列表時?否則你的方法似乎合理。 – nalyd88
@ nalyd88是的,這是可能的,但我創造了大約10個這樣的數組。我想我可以爲'max_len_of_array'使用一個數組。 – user10853
@DYZ我不明白這與我的問題有何關係。請澄清,如果你這樣做。 – user10853