【问题标题】:Astropy: split a FITS table into a training and testing setAstropy:将 FITS 表拆分为训练和测试集
【发布时间】:2020-06-18 10:39:37
【问题描述】:

我有一个 FITS 表,我正在使用 astropy 进行操作。我想将表随机拆分为训练和测试数据以创建两个新的 FITS 表。

我首先想到使用scikit-learn 函数test_train_split,但后来我不得不将我的数据来回转换为numpy.array

到目前为止,我已经从 FITS 文件中读取了 astropy.table.Table data 并尝试了以下操作

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

但是,我不知道如何获取索引不在indexes 中的所有行。也许有更好的方法来做到这一点?如何获得我的表的随机分区?


我表中的样本碰巧每个都有一个唯一的 ID,它是一个介于 1 和 len(data) 之间的整数。所以我想,我可以做到

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()

【问题讨论】:

    标签: python astropy


    【解决方案1】:

    我是如何做到这一点的

    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]
    

    但我不知道这是最有效的方式,还是最 Pythonic 的方式。

    【讨论】:

      【解决方案2】:

      您提到使用来自 scikit-learn 的现有 train_test_split 路由。如果这是您使用 scikit-learn 的唯一东西,那将是矫枉过正。但是,如果您已经将它用于任务的其他部分,您也可以这样做。 Astropy Tables 一开始就由 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 对 ID 进行分区:

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

      )

      对于它的价值,因为它可能会帮助您在将来更轻松地找到此类问题的答案,这将有助于更抽象地考虑您正在尝试做的事情(似乎您已经 em> 这样做,但你的问题的措辞暗示了其他):你表中的列只是 Numpy 数组——一旦它是这种形式,它们是从 FITS 文件中读取的无关紧要的。你所做的也与 Astropy 没有直接关系。问题就变成了如何随机划分一个 Numpy 数组。

      您可以找到此问题的通用答案,例如in this question。但如果你有它,使用现有的专用实用程序(如 train_test_split)也很好。

      【讨论】:

        猜你喜欢
        • 2017-11-01
        • 2017-06-11
        • 2017-08-30
        • 2017-07-17
        • 1970-01-01
        • 2023-01-24
        • 1970-01-01
        • 1970-01-01
        • 2019-12-11
        相关资源
        最近更新 更多