Hier ist eine fast * vektorisiert boolean-Indizierung basierten Ansatz, den ich in einigen anderen Stellen verwendet haben -
def boolean_indexing(v):
lens = np.array([len(item) for item in v])
mask = lens[:,None] > np.arange(lens.max())
out = np.zeros(mask.shape,dtype=int)
out[mask] = np.concatenate(v)
return out
Probelauf
In [27]: v
Out[27]: [[1], [1, 2], [3, 6, 7, 8, 9], [4]]
In [28]: out
Out[28]:
array([[1, 0, 0, 0, 0],
[1, 2, 0, 0, 0],
[3, 6, 7, 8, 9],
[4, 0, 0, 0, 0]])
* Bitte beachten Sie, dass diese geprägt als fast vektorisiert, weil die einzige hier durchgeführte Schleife am Anfang ist, wo wir die Längen der Listenelemente erhalten. Aber dieser Teil, der nicht so rechenintensiv ist, sollte minimale Auswirkungen auf die Gesamtlaufzeit haben.
Runtime Test
In diesem Abschnitt I DataFrame-based solution by @Alberto Garcia-Raboso
bin Timing, itertools-based solution by @ayhan
, wie sie scheinen gut und die boolean-Indizierung eine von diesem Posten für einen relativ größeren Datensatz mit drei Ebenen der Größenvariation über die Basis maßstab Listenelemente.
Fall # 1: Größere Grßenvariation
In [44]: v = [[1], [1,2,4,8,4],[6,7,3,6,7,8,9,3,6,4,8,3,2,4,5,6,6,8,7,9,3,6,4]]
In [45]: v = v*1000
In [46]: %timeit pd.DataFrame(v).fillna(0).values.astype(np.int32)
100 loops, best of 3: 9.82 ms per loop
In [47]: %timeit np.array(list(itertools.izip_longest(*v, fillvalue=0))).T
100 loops, best of 3: 5.11 ms per loop
In [48]: %timeit boolean_indexing(v)
100 loops, best of 3: 6.88 ms per loop
Fall # 2: Lesser Grßenvariation
In [49]: v = [[1], [1,2,4,8,4],[6,7,3,6,7,8]]
In [50]: v = v*1000
In [51]: %timeit pd.DataFrame(v).fillna(0).values.astype(np.int32)
100 loops, best of 3: 3.12 ms per loop
In [52]: %timeit np.array(list(itertools.izip_longest(*v, fillvalue=0))).T
1000 loops, best of 3: 1.55 ms per loop
In [53]: %timeit boolean_indexing(v)
100 loops, best of 3: 5 ms per loop
Fall # 3: größere Anzahl von Elementen (100 max) pro Listenelement
In [139]: # Setup inputs
...: N = 10000 # Number of elems in list
...: maxn = 100 # Max. size of a list element
...: lens = np.random.randint(0,maxn,(N))
...: v = [list(np.random.randint(0,9,(L))) for L in lens]
...:
In [140]: %timeit pd.DataFrame(v).fillna(0).values.astype(np.int32)
1 loops, best of 3: 292 ms per loop
In [141]: %timeit np.array(list(itertools.izip_longest(*v, fillvalue=0))).T
1 loops, best of 3: 264 ms per loop
In [142]: %timeit boolean_indexing(v)
10 loops, best of 3: 95.7 ms per loop
Für mich scheint es
itertools.izip_longest
geht es ziemlich gut!
gibt es keinen klaren Gewinner, müsste aber von Fall zu Fall entschieden werden!
Das scheint wirklich gut zu sein, wenn die Größenvariation innerhalb der Listenelemente groß ist, basierend auf einem schnellen Laufzeittest für einen großen Datensatz. – Divakar