3 votes

PyTables : indexation de dimensions multiples de grands tableaux

J'analyse des données d'imagerie qui consistent en de grandes matrices tridimensionnelles d'intensités de pixels avec les dimensions suivantes [frame, x, y] . Comme ils sont généralement trop gros pour être stockés en mémoire, ils résident sur le disque dur sous forme de tableaux PyTables.

Ce que j'aimerais pouvoir faire, c'est lire les intensités d'un sous-ensemble arbitraire de pixels dans toutes les images. La façon naturelle de le faire semble être l'indexation par liste :

import numpy as np
import tables

tmph5 = tables.open_file('temp.hdf5', 'w')
bigarray = tmph5.create_array('/', 'bigarray', np.random.randn(1000, 200, 100))

roipixels = [[0, 1, 2, 4, 6], [34, 35, 36, 40, 41]]
roidata = bigarray[:, roipixels[0], roipixels[1]]
# IndexError: Only one selection list is allowed

Malheureusement, il semble que PyTables ne supporte actuellement qu'un seul ensemble d'indices de liste. Un autre problème est qu'un index de liste ne peut pas contenir de doublons - je n'ai pas pu lire simultanément des pixels [1, 2] y [1, 3] puisque ma liste de coordonnées x des pixels contiendrait [1, 1] . Je sais que je peux itérer sur les lignes du tableau :

roidata = np.asarray([row[roipixels[0], roipixels[1]] for row in bigarray])

mais ces lectures itératives deviennent assez lentes pour le grand nombre d'images que je traite.

Existe-t-il une façon plus agréable de procéder ? Je suis relativement nouveau dans l'utilisation de PyTables, donc si vous avez des conseils pour organiser des ensembles de données dans de grands tableaux, j'aimerais les entendre.

3voto

Joe Kington Points 68089

Pour ce que cela vaut, je fais souvent la même chose avec des données sismiques 3D stockées au format hdf.

La lecture itérative est lente en raison des boucles imbriquées. Si vous ne faites qu'une seule boucle (plutôt que de boucler sur chaque ligne), c'est assez rapide (du moins lorsque vous utilisez h5py . En général, je ne stocke que des données de type tableau en utilisant pytables ) et fait exactement ce que vous voulez.

Dans la plupart des cas, vous voudrez itérer sur vos listes d'indicateurs, plutôt que sur chaque ligne.

En gros, vous voulez :

roidata = np.vstack([bigarray[:,i,j] for i,j in zip(*roipixels)])

Au lieu de :

roidata = np.asarray([row[roipixels[0],roipixels[1]] for row in bigarray])

S'il s'agit de votre cas d'utilisation le plus courant, l'ajustement de la taille des morceaux du tableau stocké vous aidera considérablement. Dans votre cas, vous voudrez des morceaux longs et étroits, avec la plus grande longueur le long du premier axe.

(Avertissement : je n'ai pas testé ceci avec pytables mais il fonctionne parfaitement avec h5py .)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X