Skip to content

Emit string truncation warnings for MaskedColumn - #5819

Merged
mhvk merged 5 commits into
astropy:masterfrom
taldcroft:table-truncate
May 8, 2017
Merged

mhvk merged 5 commits into
astropy:masterfrom
taldcroft:table-truncate

Conversation

@taldcroft

Copy link
Copy Markdown
Member

Closes #5817.

This also implements a workaround for numpy/numpy#8624. If we think this is important enough to backport then this bit would need to go in a separate PR.

Comment thread astropy/table/column.py Outdated
value = np.ma.asanyarray(value, dtype=self.dtype.type)

# Turn value into a flat masked array with at least 1d
vals = np.ma.atleast_1d(value).flatten()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will go wrong for >=2-d arrays of strings (which are of course not impossible...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to read so poorly -- I now see that all you are trying to do is to get the warning right.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved the comments and code organization to make the intent of this section more clear.

Comment thread astropy/table/column.py Outdated
# array to the smallest length without initing from a Python list
# of strings.
if np.any(vals.mask):
vals = vals[~vals.mask].tolist()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removes masked items, so changes the length of the list. Can this work?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, duh, this is only for the warning. Never mind....

@mhvk

mhvk commented May 2, 2017 •

Copy link
Copy Markdown
Contributor

Sorry for the noise in the comments. Might np.char.str_len help for the length?

m = np.ma.MaskedArray([np.ma.masked, 'gg'])
np.char.str_len(m)
# array([2, 2])
np.where(m.mask, 0, np.char.str_len(m))
# array([0, 2])
np.where(m.mask, 0, np.char.str_len(m)).max()
2
np.char.str_len(m)[~m.mask].max()
2

@taldcroft

Copy link
Copy Markdown
Member Author

@mhvk - I used your idea of np.char.str_len to improve the checking (also for the non-masked case).

One question is if you have a better idea for determining the itemsize for a length=1 version of an arbitrary string dtype. I used np.array('', dtype=value.dtype.type).itemsize. This works for the tested cases, but I'm not sure it is completely future-proof. Maybe we'll cross that bridge when/if numpy gets there.

Comment thread astropy/table/column.py Outdated
# itemsize for a length=1 version of the string type. Remember itemsize
# is the total length in bytes for a single item.
value_str_len = np.char.str_len(value).max()
value_itemsize = value_str_len * np.array('', dtype=value.dtype.type).itemsize

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is bizarre that the number of elements cannot be grabbed more directly!

In any case, in the current version, I'd make the string '1', just in case zero-length strings become possible (which is planned; numpy/numpy#8970).

Alternatively, I guess one could do

self_max_len = int(self.dtype.str[2:])
if value_str_len > self_max_len:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we always be sure that '1' (or any ASCII character) will be part of any future arbitrary string dtype? That was my motivation for using an empty string. I thought about your second solution as well. Even though I already used that for making the warning message, it still strikes me as bad form to parse the .str attribute like that for actual code logic. Agreed that there really should be a better way!

Anyway, I'll do something to avoid using the zero-length string.

Comment thread astropy/table/column.py Outdated
# - Make version of ``value`` that is flat masked array with at least 1d
# - Get rid of any masked elements.
# - If there are any vals then check for string truncation
vals = np.ma.atleast_1d(value).flatten()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the following simplification would work, no?

value =np.ma.asanyarray(value, dtype=self.dtype.type, ndmin=1)
self._check_string_truncate(value.filled(''))

@taldcroft

taldcroft commented May 3, 2017 •

Copy link
Copy Markdown
Member Author

Humm, looks like np.char.str_len() is failing for Py3.3 + numpy 1.8. (I bet numpy 1.7 would fail too for Py3). Suggestion?

@taldcroft

Copy link
Copy Markdown
Member Author

FYI, if you are tempted to use ndmin, it doesn't appear to be in the numpy API as of numpy 1.8.

@mhvk

mhvk commented May 3, 2017

Copy link
Copy Markdown
Contributor

Should this be a good enough reason to drop support for python 3.3 for astropy 2.0? The route via lists that you had earlier could be quite bad for very large arrays. In another PR, we have also been wondering about dropping numpy 1.7... See #6000.

@taldcroft

Copy link
Copy Markdown
Member Author

Based on initial #6000 discussion I'll see if this works for Py 3.3 + numpy 1.9+.

@taldcroft

Copy link
Copy Markdown
Member Author

OK, numpy 1.9 with python 3.3 and 3.4 passes tests. So if we can just update the Travis CI matrix accordingly, this should be good.

@mhvk

mhvk commented May 8, 2017

Copy link
Copy Markdown
Contributor

Since #6006 was merged, this should now be all OK, so merging!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants