issues: 314444743
This data as json
id | node_id | number | title | user | state | locked | assignee | milestone | comments | created_at | updated_at | closed_at | author_association | active_lock_reason | draft | pull_request | body | reactions | performed_via_github_app | state_reason | repo | type |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
314444743 | MDU6SXNzdWUzMTQ0NDQ3NDM= | 2059 | How should xarray serialize bytes/unicode strings across Python/netCDF versions? | 1217238 | open | 0 | 5 | 2018-04-15T19:36:55Z | 2020-11-19T10:08:16Z | MEMBER | netCDF string typesWe have several options for storing strings in netCDF files:
-
NumPy/Python string typesOn the Python side, our options are perhaps even more confusing:
- NumPy's Like pandas, we are pretty liberal with converting back and forth between fixed-length ( Current behavior of xarrayCurrently, xarray uses the same behavior on Python 2/3. The priority was faithfully round-tripping data from a particular version of Python to netCDF and back, which the current serialization behavior achieves: | Python version | NetCDF version | NumPy datatype | NetCDF datatype | | --------- | ---------- | -------------- | ------------ | | Python 2 | NETCDF3 | np.string_ / str | NC_CHAR | | Python 2 | NETCDF4 | np.string_ / str | NC_CHAR | | Python 3 | NETCDF3 | np.string_ / bytes | NC_CHAR | | Python 3 | NETCDF4 | np.string_ / bytes | NC_CHAR | | Python 2 | NETCDF3 | np.unicode_ / unicode | NC_CHAR with UTF-8 encoding | | Python 2 | NETCDF4 | np.unicode_ / unicode | NC_STRING | | Python 3 | NETCDF3 | np.unicode_ / str | NC_CHAR with UTF-8 encoding | | Python 3 | NETCDF4 | np.unicode_ / str | NC_STRING | | Python 2 | NETCDF3 | object bytes/str | NC_CHAR | | Python 2 | NETCDF4 | object bytes/str | NC_CHAR | | Python 3 | NETCDF3 | object bytes | NC_CHAR | | Python 3 | NETCDF4 | object bytes | NC_CHAR | | Python 2 | NETCDF3 | object unicode | NC_CHAR with UTF-8 encoding | | Python 2 | NETCDF4 | object unicode | NC_STRING | | Python 3 | NETCDF3 | object unicode/str | NC_CHAR with UTF-8 encoding | | Python 3 | NETCDF4 | object unicode/str | NC_STRING | This can also be selected explicitly for most data-types by setting dtype in encoding:
- Script for generating table:
```python
from __future__ import print_function
import xarray as xr
import uuid
import netCDF4
import numpy as np
import sys
for dtype_name, value in [
('np.string_ / ' + type(b'').__name__, np.array([b'abc'])),
('np.unicode_ / ' + type(u'').__name__, np.array([u'abc'])),
('object bytes/' + type(b'').__name__, np.array([b'abc'], dtype=object)),
('object unicode/' + type(u'').__name__, np.array([u'abc'], dtype=object)),
]:
for format in ['NETCDF3_64BIT', 'NETCDF4']:
filename = str(uuid.uuid4()) + '.nc'
xr.Dataset({'data': value}).to_netcdf(filename, format=format)
with netCDF4.Dataset(filename) as f:
var = f.variables['data']
disk_dtype = var.dtype
has_encoding = hasattr(var, '_Encoding')
disk_dtype_name = (('NC_CHAR' if disk_dtype == 'S1' else 'NC_STRING') +
(' with UTF-8 encoding' if has_encoding else ''))
print('|', 'Python %i' % sys.version_info[0],
'|', format[:7],
'|', dtype_name,
'|', disk_dtype_name,
'|')
```
Potential alternativesThe main option I'm considering is switching to default to This would imply two changes:
1. Attempting to serialize arbitrary bytes (on Python 2) would start raising an error -- anything that isn't ASCII would require explicitly disabling This implicit conversion would be consistent with Python 2's general handling of bytes/unicode, and facilitate reading netCDF files on Python 3 that were written with Python 2. The counter-argument is that it may not be worth changing this at this late point, given that we will be sunsetting Python 2 support by year's end. |
{ "url": "https://api.github.com/repos/pydata/xarray/issues/2059/reactions", "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
13221727 | issue |