Numpy: arregla la matriz con filas de diferentes longitudes rellenando los elementos vacíos con ceros

La funcionalidad que busco se ve algo como esto:

data = np.array([[1, 2, 3, 4], [2, 3, 1], [5, 5, 5, 5], [1, 1]]) result = fix(data) print result [[ 1. 2. 3. 4.] [ 2. 3. 1. 0.] [ 5. 5. 5. 5.] [ 1. 1. 0. 0.]] 

Estas matrices de datos con las que trabajo son muy grandes, por lo que apreciaría la solución más eficiente.

Edición: los datos se leen desde el disco como una lista de listas de python.

Este podría ser un enfoque

 def numpy_fillna(data): # Get lengths of each row of data lens = np.array([len(i) for i in data]) # Mask of valid places in each row mask = np.arange(lens.max()) < lens[:,None] # Setup output array and put elements from data into masked positions out = np.zeros(mask.shape, dtype=data.dtype) out[mask] = np.concatenate(data) return out 

Muestra de entrada, salida -

 In [222]: # Input object dtype array ...: data = np.array([[1, 2, 3, 4], ...: [2, 3, 1], ...: [5, 5, 5, 5, 8 ,9 ,5], ...: [1, 1]]) In [223]: numpy_fillna(data) Out[223]: array([[1, 2, 3, 4, 0, 0, 0], [2, 3, 1, 0, 0, 0, 0], [5, 5, 5, 5, 8, 9, 5], [1, 1, 0, 0, 0, 0, 0]], dtype=object) 

Podrías usar pandas en lugar de adormecer:

 In [1]: import pandas as pd In [2]: df = pd.DataFrame([[1, 2, 3, 4], ...: [2, 3, 1], ...: [5, 5, 5, 5], ...: [1, 1]], dtype=float) In [3]: df.fillna(0.0).values Out[3]: array([[ 1., 2., 3., 4.], [ 2., 3., 1., 0.], [ 5., 5., 5., 5.], [ 1., 1., 0., 0.]]) 

utilizar np.pad() .

 In [62]: arr Out[62]: [array([0]), array([83, 74]), array([87, 61, 23]), array([71, 3, 81, 77]), array([20, 44, 20, 53, 60]), array([54, 36, 74, 35, 49, 54]), array([11, 36, 0, 98, 29, 87, 21]), array([ 1, 22, 62, 51, 45, 40, 36, 86]), array([ 7, 22, 83, 58, 43, 59, 45, 81, 92]), array([68, 78, 70, 67, 77, 64, 58, 88, 13, 56])] In [63]: max_len = np.max([len(a) for a in arr]) In [64]: np.asarray([np.pad(a, (0, max_len - len(a)), 'constant', constant_values=0) for a in arr]) Out[64]: array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [83, 74, 0, 0, 0, 0, 0, 0, 0, 0], [87, 61, 23, 0, 0, 0, 0, 0, 0, 0], [71, 3, 81, 77, 0, 0, 0, 0, 0, 0], [20, 44, 20, 53, 60, 0, 0, 0, 0, 0], [54, 36, 74, 35, 49, 54, 0, 0, 0, 0], [11, 36, 0, 98, 29, 87, 21, 0, 0, 0], [ 1, 22, 62, 51, 45, 40, 36, 86, 0, 0], [ 7, 22, 83, 58, 43, 59, 45, 81, 92, 0], [68, 78, 70, 67, 77, 64, 58, 88, 13, 56]]) 

Esto sería bueno si de alguna manera vectorizada, pero todavía soy un NOOB, ¡así que es todo lo que puedo pensar ahora!

 import numpy as np,numba as nb a=np.array([[1, 2, 3, 4], [2, 3, 1], [5, 5, 5, 5,5], [1, 1]]) @nb.jit() def f(a): l=len(max(a,key=len)) a0=np.empty(a.shape+(l,)) for n,i in enumerate(a.flat): a0[n]=np.pad(i,(0,l-len(i)),mode='constant') a=a0 return a print(f(a))