¿Cómo hacer una matriz nudo multidimensional con un tamaño de fila variable?

Me gustaría crear una matriz numpy bidimensional de matrices que tenga un número diferente de elementos en cada fila.

Molesto

cells = numpy.array([[0,1,2,3], [2,3,4]]) 

da un error

 ValueError: setting an array element with a sequence. 

Mientras Numpy sabe acerca de matrices de objetos arbitrarios, está optimizado para matrices homogéneas de números con dimensiones fijas. Si realmente necesita arreglos de matrices, mejor use una lista anidada. Pero dependiendo del uso previsto de sus datos, las diferentes estructuras de datos podrían ser incluso mejores, por ejemplo, una matriz enmascarada si tiene algunos puntos de datos no válidos.

Si realmente quieres matrices Numpy flexibles, usa algo como esto:

 numpy.array([[0,1,2,3], [2,3,4]], dtype=object) 

Sin embargo, esto creará una matriz unidimensional que almacena referencias a listas, lo que significa que perderá la mayoría de los beneficios de Numpy (procesamiento vectorial, localidad, corte, etc.).

Ahora estamos casi 7 años después de que se hizo la pregunta, y su código

 cells = numpy.array([[0,1,2,3], [2,3,4]]) 

ejecutado en numpy 1.12.0, python 3.5, no produce ningún error y cells contiene:

 array([[0, 1, 2, 3], [2, 3, 4]], dtype=object) 

Accedes a tus elementos de cells como cells[0][2] # (=2) .

Una alternativa a la solución de tom10 si desea construir su lista de matrices numpy sobre la marcha como nuevos elementos (es decir, matrices) disponibles es utilizar append :

 d = [] # initialize an empty list a = np.arange(3) # array([0, 1, 2]) d.append(a) # [array([0, 1, 2])] b = np.arange(3,-1,-1) #array([3, 2, 1, 0]) d.append(b) #[array([0, 1, 2]), array([3, 2, 1, 0])] 

Esto no está bien soportado en Numpy (por definición, casi en todas partes, una “matriz bidimensional” tiene todas las filas de igual longitud). Una lista de Python de matrices Numpy puede ser una buena solución para ti, de esta manera obtendrás las ventajas de Numpy donde puedes usarlas:

 cells = [numpy.array(a) for a in [[0,1,2,3], [2,3,4]]] 

Otra opción sería almacenar sus matrices como una matriz contigua y también almacenar sus tamaños o compensaciones. Esto requiere un poco más de reflexión conceptual sobre cómo operar en sus matrices, pero se puede hacer que una cantidad sorprendentemente grande de operaciones funcione como si tuviera una matriz bidimensional con diferentes tamaños. En los casos en que no pueden, np.split se puede utilizar para crear la lista que recomienda calocedrus. Las operaciones más fáciles son ufuncs, porque no requieren casi ninguna modificación. Aquí hay unos ejemplos:

 cells_flat = numpy.array([0, 1, 2, 3, 2, 3, 4]) # One of these is required, it's pretty easy to convert between them, # but having both makes the examples easy cell_lengths = numpy.array([4, 3]) cell_starts = numpy.insert(cell_lengths[:-1].cumsum(), 0, 0) cell_lengths2 = numpy.diff(numpy.append(cell_starts, cells_flat.size)) assert np.all(cell_lengths == cell_lengths2) # Copy prevents shared memory cells = numpy.split(cells_flat.copy(), cell_starts[1:]) # [array([0, 1, 2, 3]), array([2, 3, 4])] numpy.array([x.sum() for x in cells]) # array([6, 9]) numpy.add.reduceat(cells_flat, cell_starts) # array([6, 9]) [a + v for a, v in zip(cells, [1, 3])] # [array([1, 2, 3, 4]), array([5, 6, 7])] cells_flat + numpy.repeat([1, 3], cell_lengths) # array([1, 2, 3, 4, 5, 6, 7]) [a.astype(float) / a.sum() for a in cells] # [array([ 0. , 0.16666667, 0.33333333, 0.5 ]), # array([ 0.22222222, 0.33333333, 0.44444444])] cells_flat.astype(float) / np.add.reduceat(cells_flat, cell_starts).repeat(cell_lengths) # array([ 0. , 0.16666667, 0.33333333, 0.5 , 0.22222222, # 0.33333333, 0.44444444]) def complex_modify(array): """Some complicated function that modifies array pretend this is more complex than it is""" array *= 3 for arr in cells: complex_modify(arr) cells # [array([0, 3, 6, 9]), array([ 6, 9, 12])] for arr in numpy.split(cells_flat, cell_starts[1:]): complex_modify(arr) cells_flat # array([ 0, 3, 6, 9, 6, 9, 12]) 

En numpy 1.14.3, usando append:

 d = [] # initialize an empty list a = np.arange(3) # array([0, 1, 2]) d.append(a) # [array([0, 1, 2])] b = np.arange(3,-1,-1) #array([3, 2, 1, 0]) d.append(b) #[array([0, 1, 2]), array([3, 2, 1, 0])] 

obtienes una lista de matrices (que pueden ser de diferentes longitudes) y puedes hacer operaciones como d[0].mean() . Por otra parte,

 cells = numpy.array([[0,1,2,3], [2,3,4]]) 

aún resulta en una variedad de listas.