Как я могу превратить результат запроса таблицы H5 в таблицу астропии? - PullRequest
0 голосов
/ 10 июля 2020

Обычно я запрашиваю онлайн-базу данных с помощью SQL, но база данных не работает. У меня есть файл H5, содержащий таблицу, которую мне нужно запросить. Я запросил таблицу, используя Table.read_where('condition'), и у меня есть список numpy.void элементов для каждой строки, которые соответствуют моим критериям. Есть ли способ взять этот список строк и превратить его в таблицу Astropy? Это то, что раньше использовал весь мой код, и я бы предпочел не менять его. Вот код, который я использовал, чтобы попытаться преобразовать его в таблицу Astropy:

import tables
from astropy.table import Table
import numpy as np

Data = tables.open_file('file_path','r') #opens our .h5 file
DataTable = Data.root.TableName #Points to the table

#Queries the table for rows that meet my 'Condition', and outputs a list of numpy.void's 
#containing integers and floats. Each numpy.void represents a row in my table. 
result = [row for row in DataTable.read_where('Condition')]

#I try to turn the list of rows into a Astropy table to use in the rest of my code.
resultTable = Table(rows=result,names=('Column1','Column2','Column3'))

Я получаю следующую ошибку:

Traceback (most recent call last):

  File "<ipython-input-2-aa9501cdbf2a>", line 1, in <module>
    runfile('FilePath', wdir='FilePath')

  File "Spyder File", line 827, in runfile
    execfile(filename, namespace)

  File "Spyder File", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "File Path", line 27, in <module>
    resultTable = Table(rows=result,names=('Column1','Column2','Column3'))

  File "FilePath/python3.7/site-packages/astropy/table/table.py", line 420, in __init__
    rec_data = recarray_fromrecords(rows)

  File "FilePath/lib/python3.7/site-packages/astropy/table/np_utils.py", line 196, in recarray_fromrecords
    return np.rec.fromarrays(array_list, formats=formats)

  File "FilePath/lib/python3.7/site-packages/numpy/core/records.py", line 645, in fromarrays
    _array[_names[i]] = arrayList[i]

ValueError: Can't cast from structure to non-structure, except if the structure only has a single field.

Я попытался передать * 1009 от * до np.rec.fromrecords, чтобы проверить, действительно ли это, поскольку [документация Astropy] (https://docs.astropy.org/en/stable/table/construct_table.html#construct -table ) говорит, что он должен иметь возможность пройти через эту функцию. Работает без ошибок. Я не уверен, где отсюда go.

Мой альтернативный план - создать таблицу PyTables, состоящую из строк в result, и вытащить столбцы как numpy массивы из этого . Я бы предпочел просто использовать Astropy, поскольку код, который я использую, построен на Astropy, и было бы проще придерживаться этого, вместо того, чтобы переходить и менять его на PyTables.

1 Ответ

0 голосов
/ 12 июля 2020

Основываясь на документации для AstroPy Table , первым аргументом может быть NumPy структурированный массив или 1-мерный однородный массив (того же типа).

PyTables (таблицы) функция DataTable.read_where('Condition') возвращает массив записей NumPy, соответствующий описанию этой таблицы (также известный как dtype в терминологии NumPy). Итак, вы хотите использовать возвращенный массив для создания своей таблицы AstroPy. Вам не нужно row for row in в вызове Pytables; просто используйте result = DataTable.read_where('Condition').

Примечание. По умолчанию astropy.table будет использовать имена полей из массива NumPy. Вы можете просмотреть их с помощью (print (result.dtype). Добавление параметра names= заменяет имена по умолчанию указанными вами именами.

Обновленный код, показывающий это изменение ниже:

Data = tables.open_file('file_path','r') #opens our .h5 file
DataTable = Data.root.TableName #Points to the PyTable table

#Queries the table for rows that meet my 'Condition', and 
# returns a NumPy record array with dtype matching the table description
result = DataTable.read_where('Condition')

#reference the Numpy Array to create a AstroPy table for use in the rest of my code.
resultTable = Table(rows=result,names=('Column1','Column2','Column3'))
...