Skip to content

Consider changing sort() to not update columns in-place #9553

Closed

Description

@taldcroft

From #9536.

The current Table behavior was based on how numpy behaves both with respect to sorting a single array in place and sorting a structured array (with tbl.sort(order='sort_col')). In the latter case in particular a ref to a column is not lost during the sort operation.

My guess was that pandas would do the same, but I just tried df.sort_values('sort_col', inplace=True) and found that it does indeed make new column references.

So there is not an unambiguous precedent, though numpy and astropy Table have historically kept references. BTW, for Table it used to be the case that replacing a column in the table was slow, but no longer.

One thing I that I just appreciated is that take is actually make a deep copy of all the info attributes (e.g. meta). From that perspective we are already paying for a full independent copy of the Column or mixin, so maybe just using the new column always is better?

This would be a real API change.

Activity

  1. added
    API changePRs and issues that change an existing API, possibly requiring a deprecation period
    on Nov 7, 2019
  2. bsipocz commented on Nov 14, 2019

    @bsipocz
    Member

    @taldcroft - is this something you would have in mind for 4.0?

  3. taldcroft commented on Nov 14, 2019

    @taldcroft
    MemberAuthor

    The first time I tried this it broke some tests in ways that were not immediately obvious. I can take another look at this tomorrow and see if the problem is easy to fix. I guess 4.0 would be a good place for an API change like this.

  4. taldcroft commented on Nov 16, 2019

    @taldcroft
    MemberAuthor

    I spent some time playing around with this but there is some wacky thing going on with table indexes that are not obvious, so deferring this for now. For the record, this passes current tests:

    diff --git a/astropy/table/table.py b/astropy/table/table.py
    index b157a726b..202a41471 100644
    --- a/astropy/table/table.py
    +++ b/astropy/table/table.py
    @@ -2922,17 +2922,10 @@ class Table:
                 # Make a new sorted column.  This requires that take() also copies
                 # relevant info attributes for mixin columns.
                 new_col = col.take(indexes, axis=0)
    +            if col.info.indices:
    +                new_col = col.info.slice_indices(new_col, indexes, len(col))
     
    -            # First statement in try: will succeed if the column supports an in-place
    -            # update, and matches the legacy behavior of astropy Table.  However,
    -            # some mixin classes may not support this, so in that case just drop
    -            # in the entire new column. See #9553 and #9536 for discussion.
    -            try:
    -                col[:] = new_col
    -            except Exception:
    -                # In-place update failed for some reason, exception class not
    -                # predictable for arbitrary mixin.
    -                self[col.info.name] = new_col
    +            self[col.info.name] = new_col
     
             if sort_index is not None:
                 # undo index freeze
    

    However, it fails this test that the column is actually a new object:

    t = simple_table()[[2, 1, 0]]
    t.add_index('a')  # Things work as expected without the index
    ta = t['a']
    print(id(t.columns['a']))
    t.sort('a')
    print(id(t.columns['a']))
    print(ta is t['a'])  # gives True, should be False
    
  5. taldcroft commented on Apr 2, 2020

    @taldcroft
    MemberAuthor

    I'm closing. Looking back at this I don't see a really strong driver.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    API changePRs and issues that change an existing API, possibly requiring a deprecation periodRefactoringtablewont-fix

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions