2017-08-17 4 views
6

J'ai un dataset qui a 4 dimensions (pour l'instant ...) et j'ai besoin d'itérer dessus.Comment parcourir sur cet ensemble de données n-dimensionnel?

Pour accéder à une valeur dans la dataset, je fais ceci:

value = dataset[i,j,k,l] 

Maintenant, je peux obtenir le shape pour le dataset:

shape = [4,5,2,6] 

Les valeurs shape représentent la longueur de la dimension.

Comment, compte tenu du nombre de dimensions, puis-je parcourir tous les éléments de mon jeu de données? Voici un exemple:

for i in range(shape[0]): 
    for j in range(shape[1]): 
     for k in range(shape[2]): 
      for l in range(shape[3]): 
       print('BOOM') 
       value = dataset[i,j,k,l] 

À l'avenir, le shape peut changer. Ainsi, par exemple, shape peut avoir 10 éléments plutôt que le courant 4.

Existe-t-il une manière agréable et propre de faire cela avec Python 3?

+0

Je pense que ([récursive] http : //www.python-course.eu/recursive_functions.php) solution sera la meilleure solution pour vous. – Yonlif

+0

Copie possible de [Itérer via un tableau multidimensionnel en Python] (https://stackoverflow.com/questions/971678/iterating-through-a-multidimensional-array-in-python) –

Répondre

6

Vous pouvez utiliser itertools.product itérer sur la cartesian product de certaines valeurs (dans ce cas, les indices):

import itertools 
shape = [4,5,2,6] 
for idx in itertools.product(*[range(s) for s in shape]): 
    value = dataset[idx] 
    print(idx, value) 
    # i would be "idx[0]", j "idx[1]" and so on... 

Cependant, si c'est un tableau numpy vous voulez itérer, il pourrait être plus facile à utiliser np.ndenumerate:

import numpy as np 

arr = np.random.random([4,5,2,6]) 
for idx, value in np.ndenumerate(arr): 
    print(idx, value) 
    # i would be "idx[0]", j "idx[1]" and so on... 

Vous avez demandé des éclaircissements sur ce que fait effectivement itertools.product(*[range(s) for s in shape]). Donc je vais l'expliquer plus en détails.

Par exemple vous avez cette boucle:

for i in range(10): 
    for j in range(8): 
     # do whatever 

Cela peut aussi être écrit en utilisant product comme:

for i, j in itertools.product(range(10), range(8)): 
#          ^^^^^^^^---- the inner for loop 
#        ^^^^^^^^^-------------- the outer for loop 
    # do whatever 

Cela signifie product est juste une façon pratique de réduire le nombre de indépendant pour les boucles.

Si vous voulez convertir un nombre variable de for -loops à vous product besoin essentiellement deux étapes:

# Create the "values" each for-loop iterates over 
loopover = [range(s) for s in shape] 

# Unpack the list using "*" operator because "product" needs them as 
# different positional arguments: 
prod = itertools.product(*loopover) 

for idx in prod: 
    i_0, i_1, ..., i_n = idx # index is a tuple that can be unpacked if you know the number of values. 
           # The "..." has to be replaced with the variables in real code! 
    # do whatever 

C'est équivalent à:

for i_1 in range(shape[0]): 
    for i_2 in range(shape[1]): 
     ... # more loops 
      for i_n in range(shape[n]): # n is the length of the "shape" object 
       # do whatever 
+0

Vous n'avez pas besoin de.L'indexation utilisant '[i, j, k, l]' est équivalente à '[(i, j, k, l)]' et 'idx' est juste' (i, j, k, l) 'de sorte que vous pouvez juste indexez-le (comme illustré) avec 'dataset [idx]'. :) – MSeifert