Astropy: L'initialisation de la table avec un type structuré produit des résultats incohérents/déroutants

Créé le 23 mai 2020  ·  3Commentaires  ·  Source: astropy/astropy

La description

Une discussion dans le groupe Facebook a révélé qu'une nouvelle table vide peut être construite à partir d'une table existante en passant son dtype :

>>> oldtable.dtype
dtype([('wavelength', '<f8'), ('flux', '<f4'), ('uncertainty', '<f4')])
>>> Table(dtype=oldtable.dtype)
<Table length=0>
wavelength   flux  uncertainty
 float64   float32   float32  
---------- ------- -----------

et il est également possible de l'initialiser de manière plus piétonne

>>> newtable = Table(names=oldtable.colnames, dtype=[dt for n, dt in oldtable.dtype.descr])

mais utiliser directement l'ancien dtype si names sont déjà spécifiés lève ces exceptions :

 >>> newtable = Table(names=oldtable.colnames, dtype=oldtable.dtype)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/derek/lib/python3.8/site-packages/astropy/table/table.py", line 621, in __init__
    self._check_names_dtype(names, dtype, n_cols)
  File "/Users/derek/lib/python3.8/site-packages/astropy/table/table.py", line 873, in _check_names_dtype
    raise ValueError(f'{inp_str} must be a list or None')
ValueError: dtype must be a list or None

>>> newtable = Table(names=oldtable.colnames, dtype=oldtable.dtype.descr)
Traceback (most recent call last):
  File "/Users/derek/lib/python3.8/site-packages/astropy/table/table.py", line 1088, in _convert_data_to_col
    col = col_cls(name=name, data=data, dtype=dtype,
  File "/Users/derek/lib/python3.8/site-packages/astropy/table/column.py", line 879, in __new__
    self = super().__new__(
  File "/Users/derek/lib/python3.8/site-packages/astropy/table/column.py", line 254, in __new__
    if np.dtype(dtype).char == 'S':
TypeError: data type 'wavelength' not understood

La même chose se produit lorsque le Table est initialisé avec un tableau structuré.

Comportement prévisible


Table devrait soit générer une erreur plus significative, soit (peut-être de préférence) accepter le dtype structuré, éventuellement avec un avertissement indiquant que dtype.names sera remplacé par le names spécifié

Comportement réel



Voir au dessus. Alors que la méthode recommandée dans la documentation newtable = oldtable[:0].copy() fonctionne (et a l'avantage de copier en plus toutes les propriétés unit ), le comportement différent entre la spécification de dtype seul et avec names est potentiellement déroutant et les exceptions ne sont pas très claires.

https://github.com/astropy/astropy/blob/eeb9b7ac0e18b262fae64cd2fa46d0e1cff1e4d5/astropy/table/table.py#L592 -L594

"décompresse" le dtype automatiquement lorsqu'aucune autre information names n'est disponible, et la même chose peut être faite avec l'ensemble names (mais en éliminant dtype.names , puisque names devrait certainement avoir la priorité).

Sur une note légèrement connexe, il serait pratique d'avoir une méthode pour obtenir directement toutes les unités des colonnes du tableau sous une forme qui pourrait être passée sous la forme units= . Bien sûr, on peut revenir à la méthode newtable = oldtable[:0].copy() , mais si la modification des noms ou des types est souhaitée, une telle option serait utile.

Détails du système

Astropy version 4.2.dev112+g595484597.
Date : 2020-05-22T19:44:39
Plate-forme : macOS-10.12.6-x86_64-i386-64bit
Exécutable : /sw/bin/python3.8
Version Python complète :
3.8.3 (par défaut, 14 mai 2020, 22:17:35)
[Clang 9.0.0 (clang-900.0.39.2)]

Versions de paquet :
Numpy : 1.19.0rc1
Scipy : 1.4.1
Matplotlib : 3.2.1
h5py : 2.9.0
Pandas : non disponible
Cython : 0.29.16

Bug table

Tous les 3 commentaires

Merci! Qu'est-ce que c'était exactement oldtable ? Est-il possible de fournir un extrait complètement reproductible ?

import numpy as np
from astropy.table import Table
arr = np.ones(2, dtype=np.dtype([('A', 'i'), ('B', 'f4'), ('C', 'f8')]))
tab1 = Table(arr)
tab1

tab2 = Table(dtype=tab1.dtype)
tab2

tab3 = Table(names=['X', 'Y', 'Z'], dtype=[dt for n, dt in tab1.dtype.descr])
tab3

produit la sortie suivante :

<Table length=2>
  A      B       C   
int32 float32 float64
----- ------- -------
    1     1.0     1.0
    1     1.0     1.0

<Table length=0>
  A      B       C   
int32 float32 float64
----- ------- -------

<Table length=0>
  X      Y       Z   
int32 float32 float64
----- ------- -------

tandis que

>>> tab3 = Table(names=['X', 'Y', 'Z'], dtype=tab1.dtype)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 621, in __init__
    self._check_names_dtype(names, dtype, n_cols)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 873, in _check_names_dtype
    raise ValueError(f'{inp_str} must be a list or None')
ValueError: dtype must be a list or None
>>> tab3 = Table(names=['X', 'Y', 'Z'], dtype=tab1.dtype.descr)
Traceback (most recent call last):
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 1088, in _convert_data_to_col
    col = col_cls(name=name, data=data, dtype=dtype,
  File "/sw/lib/python3.8/site-packages/astropy/table/column.py", line 879, in __new__
    self = super().__new__(
  File "/sw/lib/python3.8/site-packages/astropy/table/column.py", line 254, in __new__
    if np.dtype(dtype).char == 'S':
TypeError: data type 'A' not understood

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 624, in __init__
    init_func(data, names, dtype, n_cols, copy)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 955, in _init_from_list
    col = self._convert_data_to_col(col, copy, default_name, dtype, name)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 1092, in _convert_data_to_col
    raise ValueError('unable to convert data to Column for Table')
ValueError: unable to convert data to Column for Table



md5-9116051d321cf97db138d26f38a78850



>>> tab3 = Table(arr, dtype=tab1.dtype.descr)
Traceback (most recent call last):
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 1088, in _convert_data_to_col
    col = col_cls(name=name, data=data, dtype=dtype,
  File "/sw/lib/python3.8/site-packages/astropy/table/column.py", line 879, in __new__
    self = super().__new__(
  File "/sw/lib/python3.8/site-packages/astropy/table/column.py", line 254, in __new__
    if np.dtype(dtype).char == 'S':
TypeError: data type 'A' not understood

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 624, in __init__
    init_func(data, names, dtype, n_cols, copy)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 1108, in _init_from_ndarray
    self._init_from_list(cols, names, dtype, n_cols, copy)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 955, in _init_from_list
    col = self._convert_data_to_col(col, copy, default_name, dtype, name)
  File "/sw/lib/python3.8/site-packages/astropy/table/table.py", line 1092, in _convert_data_to_col
    raise ValueError('unable to convert data to Column for Table')
ValueError: unable to convert data to Column for Table

Voir #10419.

Cette page vous a été utile?
0 / 5 - 0 notes