Астропия: разбить таблицу FITS на тренировочный и тестовый набор - PullRequest
0 голосов
/ 05 марта 2020

У меня есть таблица FITS, которой я манипулирую астропией. Я хотел бы разбить таблицу на данные обучения и тестирования случайным образом, чтобы создать две новые таблицы FITS.

Сначала я подумал об использовании функции scikit-learn test_train_split, но потом мне пришлось бы конвертировать мои данные назад и вперед в numpy.array.

До сих пор я прочитал astropy.table.Table data из файла FITS и попробовал следующее

training_fraction = 0.5
n = len(data)
indexes = random.sample(range(n), k=int(n*training_fraction))
testing_sample = data[indexes]
training_sample = ?

Но тогда я не знаю, как получить все строки, индексы которых не в indexes. Возможно, есть лучший способ сделать это? Как я могу получить случайный раздел моей Таблицы?


Каждый из образцов в моей таблице имеет уникальный идентификатор, который является целым числом от 1 до len (данные). Итак, я решил, что могу сделать

indexes = random.sample(range(1, n+1), k=int(n*training_fraction))
testing_sample = data[data['ID'] in indexes]
training_sample = data[data['ID'] not in indexes]

, но первая строка поднимает ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Вы упомянули, что используете существующую train_test_split маршрутизацию от scikit-learn. Если вы используете only , для которого вы используете scikit-learn, это было бы излишним. Но если вы уже используете его для других частей вашей задачи, вы можете также. Астропия Таблицы уже поддерживаются массивами Numpy, поэтому вам не нужно «конвертировать данные назад и вперед».

Поскольку столбец 'ID' вашей таблицы индексирует строки в вашей таблице было бы полезно формально установить его как index вашей таблицы, чтобы значения ID могли использоваться для индексации строк в таблице (независимо от их фактического позиционного индекса). Например:

>>> from astropy.table import Table
>>> import numpy as np
>>> t = Table({
...     'ID': [1, 3, 5, 6, 7, 9],
...     'a': np.random.random(6),
...     'b': np.random.random(6)
... })
>>> t
<Table length=6>
  ID           a                   b         
int64       float64             float64      
----- ------------------- -------------------
    1  0.7285295918917892  0.6180944983953155
    3  0.9273855839237182 0.28085439237508925
    5  0.8677312765220222  0.5996267567496841
    6 0.06182255608446752  0.6604620336092745
    7 0.21450048405835265  0.5351066893214822
    9   0.928930682667869  0.8178640424254757

Затем установите 'ID' в качестве индекса таблицы:

>>> t.add_index('ID')

Используйте train_test_split для разделения идентификаторов, как вам нужно:

>>> train_ids, test_ids = train_test_split(t['ID'], test_size=0.2)
>>> train_ids
<Column name='ID' dtype='int64' length=4>
7
9
5
1
>>> test_ids
<Column name='ID' dtype='int64' length=2>
6
3
>>> train_set = t.loc[train_ids]
>>> test_set = t.loc[test_ids]
>>> train_set
<Table length=4>
  ID           a                  b         
int64       float64            float64      
----- ------------------- ------------------
    7 0.21450048405835265 0.5351066893214822
    9   0.928930682667869 0.8178640424254757
    5  0.8677312765220222 0.5996267567496841
    1  0.7285295918917892 0.6180944983953155
>>> test_set
<Table length=2>
  ID           a                   b         
int64       float64             float64      
----- ------------------- -------------------
    6 0.06182255608446752  0.6604620336092745
    3  0.9273855839237182 0.28085439237508925

(Примечание:

>>> isinstance(t['ID'], np.ndarray)
True
>>> type(t['ID']).__mro__
(astropy.table.column.Column,
 astropy.table.column.BaseColumn,
 astropy.table._column_mixins._ColumnGetitemShim,
 numpy.ndarray,
 object)

)

Для чего бы это ни стоило, поскольку в будущем это может помочь вам легче находить ответы на подобные проблемы, это поможет рассмотреть, что вы Вы пытаетесь сделать это более абстрактно (кажется, вы уже делаете , но формулировка вашего вопроса говорит об обратном): столбцы в вашей таблице - это просто Numpy массивы - как только они в такой форме, это не имеет значения, что они были прочитаны из файлов FITS. То, что вы делаете, не имеет никакого отношения к Астропии. Просто возникает вопрос, как случайным образом разбить массив Numpy.

Вы можете найти общие c ответы на эту проблему, например, в этом вопросе . Но также неплохо использовать существующую специализированную утилиту, такую ​​как train_test_split, если она у вас есть.

0 голосов
/ 06 марта 2020

Как мне удалось это сделать, было

training_indexes = sorted(random.sample(range(n), k=int(n*training_fraction)))
testing_indexes = [i for i in range(n) if i not in training_indexes]


testing_sample = data[testing_indexes]
training_sample = data[training_indexes]

Но я не знаю, является ли это наиболее эффективным или наиболее питонным c способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...