Проблема с PyTables - разные результаты при переборе подмножества таблицы

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

  •  20-09-2019
  •  | 
  •  

Вопрос

Я новичок в PyTables и собираюсь использовать его для обработки данных, сгенерированных в результате моделирования на основе агентов и сохраненных в HDF5.Я работаю с тестовым файлом размером 39 МБ и испытываю некоторую странность.Вот макет таблицы:

    /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,)

Вот как я получаю к нему доступ на 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

Теперь вот где все становится странным.

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

Я не понимаю, почему значения искажаются, когда я перебираю всю таблицу, но не тогда, когда я беру небольшое подмножество из всего набора строк.Я уверен, что это ошибка в том, как я использую библиотеку, поэтому я был бы чрезвычайно признателен за любую помощь в этом вопросе.

Это было полезно?

Решение

Это очень распространенный момент путаницы при повторении Table объект,

Когда вы перебираете Table тип элемента, который вы получаете, - это не данные в элементе, а средство доступа к таблице в текущей строке.Так что с

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

вы создаете список средств доступа к строке, которые все указывают на "текущую" строку таблицы, последнюю строку.Но когда ты делаешь

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

вы используете средство доступа при построении списка.

Решение для получения всех необходимых данных при построении списка с помощью средства доступа на каждой итерации.Есть два варианта

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

или

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

Первый создает список кортежей.Последний возвращает объект NumPy void.IIRC, второй способ быстрее, но первый может иметь больше смысла для ваших целей.

Вот хорошее объяснение от разработчика PyTables. В будущих версиях при печати объекта доступа к строке могут не просто отображаться данные, а указываться, что это объект доступа к строке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top