PyTables problème - des résultats différents lorsque vous parcourez sous-ensemble de la table

StackOverflow https://stackoverflow.com/questions/1929973

  •  20-09-2019
  •  | 
  •  

Question

Je suis nouveau à PyTables, et je cherche à l'utiliser pour traiter les données générées à partir d'une simulation de modélisation à base d'agents et stockés dans HDF5. Je travaille avec un fichier de test 39 Mo, et je éprouve une certaine étrangeté. Voici la présentation de la table:

    /example/agt_coords (Table(2000000,)) ''
  description := {
  "agent": Int32Col(shape=(), dflt=0, pos=0),
  "x": Float64Col(shape=(), dflt=0.0, pos=1),
  "y": Float64Col(shape=(), dflt=0.0, pos=2)}
  byteorder := 'little'
  chunkshape := (20000,)

Voilà comment j'accéder en Python:

from tables import *
>>> h5file = openFile("alternate_hose_test.h5", "a")

h5file.root.example.agt_coords
/example/agt_coords (Table(2000000,)) ''
  description := {
  "agent": Int32Col(shape=(), dflt=0, pos=0),
  "x": Float64Col(shape=(), dflt=0.0, pos=1),
  "y": Float64Col(shape=(), dflt=0.0, pos=2)}
  byteorder := 'little'
  chunkshape := (20000,)
>>> coords = h5file.root.example.agt_coords

Maintenant, voici où les choses deviennent bizarre.

[x for x in coords[1:100] if x['agent'] == 1]
[(1, 25.0, 78.0), (1, 25.0, 78.0)]
>>> [x for x in coords if x['agent'] == 1]
[(1000000, 25.0, 78.0), (1000000, 25.0, 78.0)]
>>> [x for x in coords.iterrows() if x['agent'] == 1]
[(1000000, 25.0, 78.0), (1000000, 25.0, 78.0)]
>>> [x['agent'] for x in coords[1:100] if x['agent'] == 1]
[1, 1]
>>> [x['agent'] for x in coords if x['agent'] == 1]
[1, 1]

Je ne comprends pas pourquoi les valeurs sont foiré quand j'itérer sur toute la table, mais pas quand je prends un petit sous-ensemble de l'ensemble de lignes. Je suis sûr que ce soit une erreur dans la façon dont j'utilise la bibliothèque, de sorte que toute aide dans cette affaire serait extrêmement apprécié.

Était-ce utile?

La solution

Ce point est très commun de confusion lorsque vous parcourez objet Table,

Lorsque vous itérer sur une Table le type d'élément que vous obtenez ne sont pas les données à l'élément, mais un accesseur à la table à la ligne actuelle. Donc, avec

[x for x in coords if x['agent'] == 1]

vous créez une liste de accesseurs de ligne qui pointent tous vers le « courant » ligne de la table, la dernière ligne. Mais quand vous faites

[x["agent"] for x in coords if x['agent'] == 1]

vous utilisez l'accesseur que vous construisez la liste.

La solution pour obtenir toutes les données dont vous avez besoin que vous construisez la liste, en utilisant l'accesseur à chaque itération. Il y a deux options

[x[:] for x in coords if x['agent'] == 1]

ou

[x.fetch_all_fields() for x in coords if x['agent'] == 1]

L'ancien construit une liste de tuples. Celui-ci retourne un objet vide NumPy. IIRC, le second est plus rapide, mais l'ancien serait plus logique à des fins vous.

Voici une bonne explication de le développeur PyTables. Dans les versions ultérieures, l'impression d'un objet accesseur ligne ne peut pas simplement afficher les données, mais indiquent que c'est un objet accesseur ligne .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top