Skip to content

Can't add row to table with, e.g., SkyCoord column #5745

Closed

Description

@dmopalmer

Starting with the documented way of making a table:

from astropy.table import Table
from astropy.time import Time
from astropy.coordinates import SkyCoord
tm = Time(['2000:002', '2002:345'])
sc = SkyCoord([10, 20], [-45, +40], unit='deg')
t = Table([tm, sc], names=['time', 'skycoord'])
print(t)

gives

         time          skycoord
                       deg,deg
--------------------- ----------
2000:002:00:00:00.000 10.0,-45.0
2002:345:00:00:00.000  20.0,40.0

But if I try to add another row:

# Add another row
t.add_row((Time('2017:001'),sc[0]))

I get

ValueError: Unable to insert row because of exception in column 'time':
'Time' object has no attribute 'insert'

Trying different things:

t = Table([[tm[0]],[sc[0]]], names=['time', 'skycoord'])
t.add_row([tm[1],sc[1]])

works giving:

         time                               skycoord                      
--------------------- ----------------------------------------------------
2000:002:00:00:00.000 <SkyCoord (ICRS): (ra, dec) in deg
    ( 10., -45.)>
2002:345:00:00:00.000 <SkyCoord (ICRS): (ra, dec) in deg
    ( 20.,  40.)>

So if you use astropy array objects, you can't add rows. But if you use scalar values, you can add rows and later extract the values as a list .

Activity

  1. kakirastern commented on Feb 25, 2019

    @kakirastern
    Contributor

    Hi, can I work on this Issue?

  2. kakirastern commented on Feb 25, 2019

    @kakirastern
    Contributor

    I have checked that the same issue persists for astropy v3.2.dev23909. Maybe some documentation to clarify is necessary? Or, can an insert attribute be added to the SkyCoord object as a convenience?

    So in my effort to reproduce the error, if I do the following:

    from astropy.table import Table
    from astropy.time import Time
    from astropy.coordinates import SkyCoord
    tm = Time(['2000:002', '2002:345'])
    sc = SkyCoord([10, 20], [-45, +40], unit='deg')
    t = Table([tm, sc], names=['time', 'skycoord'])
    print(t)
    

    I do indeed get the table:

             time          skycoord 
                           deg,deg  
    --------------------- ----------
    2000:002:00:00:00.000 10.0,-45.0
    2002:345:00:00:00.000  20.0,40.0
    

    And when I tried to use add the row as suggested by @dmopalmer as:

    # Add another row
    t.add_row((Time('2017:001'),sc[0]))
    

    The following errors ensue:

    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    ~/astropy/astropy/table/table.py in insert_row(self, index, vals, mask)
       2339 
    -> 2340                 newcol = col.insert(index, val, axis=0)
       2341                 if not isinstance(newcol, BaseColumn):
    
    ~/astropy/astropy/coordinates/sky_coordinate.py in __getattr__(self, attr)
        599         raise AttributeError("'{0}' object has no attribute '{1}'"
    --> 600                              .format(self.__class__.__name__, attr))
        601 
    
    AttributeError: 'SkyCoord' object has no attribute 'insert'
    
    During handling of the above exception, another exception occurred:
    
    ValueError                                Traceback (most recent call last)
    <ipython-input-5-a56775b2e898> in <module>
          1 # Add another row
    ----> 2 t.add_row((Time('2017:001'),sc[0]))
    
    ~/astropy/astropy/table/table.py in add_row(self, vals, mask)
       2228              3   6   9
       2229         """
    -> 2230         self.insert_row(len(self), vals, mask)
       2231 
       2232     def insert_row(self, index, vals=None, mask=None):
    
    ~/astropy/astropy/table/table.py in insert_row(self, index, vals, mask)
       2362         except Exception as err:
       2363             raise ValueError("Unable to insert row because of exception in column '{0}':\n{1}"
    -> 2364                              .format(name, err))
       2365         else:
       2366             self._replace_cols(columns)
    
    ValueError: Unable to insert row because of exception in column 'skycoord':
    'SkyCoord' object has no attribute 'insert'
    
  3. changed the title [-]Can't add row to table with, e.g., Time column[/-] [+]Can't add row to table with, e.g., SkyCoord column[/+] on Feb 25, 2019
  4. bsipocz commented on Feb 25, 2019

    @bsipocz
    Member

    Thanks @kakirastern for the follow-up. It indeed seems that for Time objects this issue has been solved, but not yet for SkyCoord. I've updated the labels and title accordingly.

  5. kakirastern commented on Feb 26, 2019

    @kakirastern
    Contributor

    Sure @bsipocz! I will open a PR and try and find a solution soon.

  6. kakirastern commented on Mar 9, 2019

    @kakirastern
    Contributor

    I found this in the latest docs today: http://docs.astropy.org/en/latest/table/mixin_columns.html#details-and-caveats, which says something like "Adding or inserting a row works as expected only for mixin classes that are mutable (data can changed internally) and that have an insert() method. Quantity and Time support insert() but for example SkyCoord does not. If one tried to insert a row into a table with a SkyCoord column then an exception... would occur." So maybe it would be better to suggest a workaround in the documentation instead of attempting to change the code?

  7. kakirastern commented on Mar 9, 2019

    @kakirastern
    Contributor

    Or, should I look into adding an insert() method for SkyCoord? Like using something similar to the following for Quantity?:

    def insert(self, obj, values, axis=None):
            """
            Insert values along the given axis before the given indices and return
            a new `~astropy.units.Quantity` object.
    
            This is a thin wrapper around the `numpy.insert` function.
    
            Parameters
            ----------
            obj : int, slice or sequence of ints
                Object that defines the index or indices before which ``values`` is
                inserted.
            values : array-like
                Values to insert.  If the type of ``values`` is different
                from that of quantity, ``values`` is converted to the matching type.
                ``values`` should be shaped so that it can be broadcast appropriately
                The unit of ``values`` must be consistent with this quantity.
            axis : int, optional
                Axis along which to insert ``values``.  If ``axis`` is None then
                the quantity array is flattened before insertion.
    
            Returns
            -------
            out : `~astropy.units.Quantity`
                A copy of quantity with ``values`` inserted.  Note that the
                insertion does not occur in-place: a new quantity array is returned.
    
            Examples
            --------
            >>> import astropy.units as u
            >>> q = [1, 2] * u.m
            >>> q.insert(0, 50 * u.cm)
            <Quantity [ 0.5,  1.,  2.] m>
    
            >>> q = [[1, 2], [3, 4]] * u.m
            >>> q.insert(1, [10, 20] * u.m, axis=0)
            <Quantity [[  1.,  2.],
                       [ 10., 20.],
                       [  3.,  4.]] m>
    
            >>> q.insert(1, 10 * u.m, axis=1)
            <Quantity [[  1., 10.,  2.],
                       [  3., 10.,  4.]] m>
    
            """
            out_array = np.insert(self.value, obj, self._to_own_unit(values), axis)
            return self._new_view(out_array)
    

    Would that work? (I reckon it is more complex than that, but would like to confirm... )

  8. bsipocz commented on Mar 9, 2019

    @bsipocz
    Member

    Or, should I look into adding an insert() method for SkyCoord?

    I would naively say yes, but let's ping the coordinates maintainers @eteq @adrn to comment on it.

  9. kakirastern commented on Mar 10, 2019

    @kakirastern
    Contributor

    I have a feeling that the code involved to introduce an insert property to SkyCoord would be a lot more complicated than for either Time or Quantity...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions