2010-08-02 8 views

Répondre

17

Alors que Numpy sait sur les tableaux d'objets arbitraires, il est optimisé pour les tableaux homogènes de nombres avec des dimensions fixes. Si vous avez vraiment besoin de tableaux de tableaux, mieux vaut utiliser une liste imbriquée. Mais en fonction de l'utilisation prévue de vos données, différentes structures de données peuvent être encore meilleures, par ex. un tableau masqué si vous avez des points de données invalides.

Si vous voulez vraiment des tableaux NumPy flexibles, utilisez quelque chose comme ceci:

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

Cependant, cela va créer un tableau à une dimension qui stocke des références à des listes, ce qui signifie que vous perdrez la plupart des avantages de Numpy (traitement vectoriel, localité, découpage, etc.).

12

Ceci n'est pas bien supporté dans Numpy (par définition, presque partout, un "tableau bidimensionnel" a toutes les lignes de longueur égale). Une liste Python de tableaux NumPy peut être une bonne solution pour vous, comme cette façon, vous obtiendrez les avantages de Numpy où vous pouvez les utiliser:

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

Nous sommes maintenant on lui a demandé près de 7 ans après la question, et votre code

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

exécuté en numpy 1.12.0, python 3.5, ne produit aucune erreur et cells contient:

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

Vous accédez à votre cells éléments comme cells[0][2] # (=2).

Une alternative à la solution de tom10 si vous voulez construire votre liste des tableaux numpy à la volée de nouveaux éléments (c.-à-tableaux) deviennent disponibles est d'utiliser 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])] 
+0

Le problème est que vous ne pouvez toujours pas utiliser d.mean(), d.flatten(), etc. – episodeyang

1

Une autre option serait de stocker votre les tableaux sous la forme d'un tableau contigu et stockent également leurs tailles ou leurs décalages. Cela nécessite un peu plus de réflexion conceptuelle sur la façon de fonctionner sur vos tableaux, mais un nombre étonnamment élevé d'opérations peuvent être effectuées pour fonctionner comme si vous aviez un tableau bidimensionnel avec des tailles différentes. Dans les cas où ils ne peuvent pas, alors np.split peut être utilisé pour créer la liste que recommande Calocedrus. Les opérations les plus simples sont les ufunc, car elles ne nécessitent pratiquement aucune modification. Voici quelques exemples:

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])