Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

numpy 2.0 copy-keyword and trapz vs trapezoid #8865

Merged
merged 5 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ Bug fixes
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
- do not cast `_FillValue`/`missing_value` in `CFMaskCoder` if `_Unsigned` is provided
(:issue:`8844`, :pull:`8852`).
- Adapt handling of copy keyword argument in scipy backend for numpy >= 2.0dev
(:issue:`8844`, :pull:`8851`).
- Adapt handling of copy keyword argument for numpy >= 2.0dev
(:issue:`8844`, :pull:`8851`, :pull:`8865``).
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
- import trapz/trapezoid depending on numpy version.
(:issue:`8844`, :pull:`8865`).
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.



Documentation
~~~~~~~~~~~~~
Expand Down
15 changes: 13 additions & 2 deletions xarray/coding/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
unpack_for_encoding,
)
from xarray.core import indexing
from xarray.core.utils import module_available
from xarray.core.variable import Variable
from xarray.namedarray.parallelcompat import get_chunked_array_type
from xarray.namedarray.pycompat import is_chunked_array

HAS_NUMPY_2_0 = module_available("numpy", minversion="2.0.0.dev0")


def create_vlen_dtype(element_type):
if element_type not in (str, bytes):
Expand Down Expand Up @@ -156,8 +159,12 @@ def bytes_to_char(arr):

def _numpy_bytes_to_char(arr):
"""Like netCDF4.stringtochar, but faster and more flexible."""
# adapt handling of copy-kwarg to numpy 2.0
# see https://github.com/numpy/numpy/issues/25916
# and https://github.com/numpy/numpy/pull/25922
copy = None if HAS_NUMPY_2_0 else False
# ensure the array is contiguous
arr = np.array(arr, copy=False, order="C", dtype=np.bytes_)
arr = np.array(arr, copy=copy, order="C", dtype=np.bytes_)
return arr.reshape(arr.shape + (1,)).view("S1")


Expand Down Expand Up @@ -199,8 +206,12 @@ def char_to_bytes(arr):

def _numpy_char_to_bytes(arr):
"""Like netCDF4.chartostring, but faster and more flexible."""
# adapt handling of copy-kwarg to numpy 2.0
# see https://github.com/numpy/numpy/issues/25916
# and https://github.com/numpy/numpy/pull/25922
copy = None if HAS_NUMPY_2_0 else False
# based on: http://stackoverflow.com/a/10984878/809705
arr = np.array(arr, copy=False, order="C")
arr = np.array(arr, copy=copy, order="C")
dtype = "S" + str(arr.shape[-1])
return arr.view(dtype).reshape(arr.shape[:-1])

Expand Down
15 changes: 11 additions & 4 deletions xarray/tests/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@
except ImportError:
pass

# from numpy version 2.0 trapz is deprecated and renamed to trapezoid
# remove once numpy 2.0 is the oldest supported version
try:
from numpy import trapezoid # type: ignore[attr-defined,unused-ignore]
except ImportError:
from numpy import trapz as trapezoid

sparse_array_type = array_type("sparse")

pytestmark = [
Expand Down Expand Up @@ -6999,7 +7006,7 @@ def test_integrate(dask) -> None:
actual = da.integrate("x")
# coordinate that contains x should be dropped.
expected_x = xr.DataArray(
np.trapz(da.compute(), da["x"], axis=0),
trapezoid(da.compute(), da["x"], axis=0),
dims=["y"],
coords={k: v for k, v in da.coords.items() if "x" not in v.dims},
)
Expand All @@ -7012,7 +7019,7 @@ def test_integrate(dask) -> None:
# along y
actual = da.integrate("y")
expected_y = xr.DataArray(
np.trapz(da, da["y"], axis=1),
trapezoid(da, da["y"], axis=1),
dims=["x"],
coords={k: v for k, v in da.coords.items() if "y" not in v.dims},
)
Expand Down Expand Up @@ -7093,7 +7100,7 @@ def test_cumulative_integrate(dask) -> None:
@pytest.mark.filterwarnings("ignore:Converting non-nanosecond")
@pytest.mark.parametrize("dask", [True, False])
@pytest.mark.parametrize("which_datetime", ["np", "cftime"])
def test_trapz_datetime(dask, which_datetime) -> None:
def test_trapezoid_datetime(dask, which_datetime) -> None:
rs = np.random.RandomState(42)
if which_datetime == "np":
coord = np.array(
Expand Down Expand Up @@ -7124,7 +7131,7 @@ def test_trapz_datetime(dask, which_datetime) -> None:
da = da.chunk({"time": 4})

actual = da.integrate("time", datetime_unit="D")
expected_data = np.trapz(
expected_data = trapezoid(
da.compute().data,
duck_array_ops.datetime_to_numeric(da["time"].data, datetime_unit="D"),
axis=0,
Expand Down
Loading