Repository navigation
Change Table behavior when setting column: default to replace - #5556
Conversation
|
I like the change in principle for normal columns, but am a bit worried about how it affects setting the mask: if you do Need to think a bit about what behaviour would be best... |
|
@mhvk - yes, so this is something to consider. In retrospect introducing the idiom of Two ways to handle this which would fix the test failure and eliminate the need for the patch in the PR to the test function related to masking:
Upshot - for the mask issue we might want to consider a private |
|
How about we do use a private attribute such that mask is updated in place, but at the same time deprecate the use of Along similar lines: is it an idea to deprecate the in-place setting instead of trying it when |
Offhand I'm not sure I would get that pedantic. It's still nice to do stuff like |
|
OK, agreed. But deprecating |
|
👍 if this fixes #2630 . More tests to establish the behaviour of this fundamental table operation would be good, no? Most of the discussion with @mhvk above concerns To be honest, the discussion and suggestions how to handle mask above are a bit over my head. Would probably be good to get one or two more people familar with Just one question concerning: >>> from astropy.table import Table, Column
>>> table = Table()
>>> table['a'] = Column([1, 2, 3], unit='m', description='original')
>>> table['a'] = [4, 5, 6]Before this PR, this updated the values, but preserved |
|
@cdeil - thanks for having a look and thinking about this.
No new tests were added because there were existing tests of masking that failed. If you look at the first commit dd8ea97 there was a change to an explicit test of masking in About the light testing, this change is very simple in substance since it just delegates to In the |
Correct. The column is entirely replaced with whatever value is on the right side. I will update the API change entry to be even more clear. Agreed that someone like @astrofrog should weigh in. I also thought about sending a separate email to astropy-dev to allow for comment. I did this already, but perhaps under the label |
|
OK, I sent email to astropy-dev. |
Thanks for explaining. I agree there's not need to add the extra test then. |
| self.columns[item][:] = value | ||
| try: | ||
| # See definition of mask property for discussion of next line. | ||
| assert not getattr(self, '_setitem_inplace', False) |
There was a problem hiding this comment.
I've used this structure with an assert statement earlier myself, but was warned that all assert statements are skipped if one runs python with optimize (i.e., after python3 -O, typing assert False does not do anything...). So,
# The below statement is to support self.mask[col] = value.
# If that is deprecated, this can be removed.
if getattr(self, '_setitem_inplace', False):
try:
self.replace_column(item, value)
return
except Exception:
pass
self.columns[item][:] = value
There was a problem hiding this comment.
Ouch, this is good to know. There are a few places (~50) in the code where an assert is used, so you suggest that ideally we should get rid of those?
There was a problem hiding this comment.
An assert is fine if it tests something that is expected to be true -- it would seem OK to omit that test when one optimizes -- but not when it is used to decide which logical path to take. So, I guess OK except in try/except clauses.
That said, obviously it is better to do
if <something-unlikely>:
raise ShouldNotHappenError('...')
|
This looks all OK except for the one remaining comment. |
modifies the galaxy_table in-place, as recommended by @taldcroft, in a first attempt to make Halotools compatible with astropy/astropy#5556.
|
Based on discussion in astropy/halotools#637, I think we need a follow-on PR to issue a warning when replacing a column that is a slice. This condition would simply be if the column is an ndarray subclass and I also thought about possible ways to warn if the replacement might be doing something unexpected, with a config var to control this. This is obviously a bit trickier. For instance replacing a column with data of the same type but losing metadata. Or even just issuing a warning with a reference to the calling line any time a replacement is done, for debugging purposes. Any thoughts? |
|
Dang, I forgot that |
This option sounds to me like it's too complicated. I think it's OK to keep the change for 1.3. Yes, it's a change in behaviour and it will bite a few people. @taldcroft - If you're concerned with doing this change in 1.3, maybe postponing it to 2.0, i.e. a major version jump, is an option? |
|
@cdeil - in fact Pandas does have an option to control warnings for copy/replace issues. I think the pandas stuff is a bit overcomplicated, but the #5586 warnings should be manageable. I'd like to get this for 1.3 if possible! |
Add methods to help with potential problems from #5556
Add methods to help with potential problems from #5556
…e is explicitly modified in-place in accord with astropy/astropy#5556. This change has previously been brought as part of astropy#637 by b28fe15. However, as that PR is entirely unrelated to this bugfix, astropy#637 will instead be rebased against this commit for clarity. Merging this PR will also resolve the test failures that occur in astropy#638. @bsipocz and/or @eteq - let me know if you know how to handle the git rewrite in a more elegant way (e.g., rolling back b28fe15), otherwise I'm fine with simply locally rebasing astropy#637, locally resolving the conflict, and then force-pushing astropy#637.
This PR has a very simple code change so that when setting an existing Table column the code first tries to call
replace_column, and only if that fails it tries the old behavior of doing an inplace update. So in the past it was always an inplace update:With this PR:
It might happen that
replace_columnwill fail (e.g. ifval = 1) in which case the inplace update will happen.On the whole I believe that this new behavior is generally more intuitive. It matches how pandas behaves, and matches the new (post astropy 1.0) basic concept that a table is a collection of independent columns. The inplace update was previously forced by using a numpy structured array underneath to hold the table data.
I have been increasingly bothered by the inplace update behavior and the problems it creates (e.g. #2630). I previously have argued that changing this behavior would introduce unexpected behaviors (#3809). In reviewing my arguments I think those problems are definitely corner cases and not likely to impact many people. In short I have changed my mind!
One thing to be aware of is something like this:
I'm not sure how surprising or problematic this would be. One small variant of this PR is to require that the right-hand side be either a Column subclass or a mixin column. That would eliminate the above, but at the cost of less consistent / simple behavior. For instance if
t['a']were aTimemixin and you didt['a'] = [3, 4]then it fails because you cannot to an inplace assignment to aTimeobject.I've been thinking about this change for some time, but seeing #2630 and the complications that come up made me seriously consider this API change.
@cdeil @mhvk @astrofrog