Skip to content

Commit e7a9c5f

Browse files
authored
[ENH] Suppress __array_wrap__ warning in numpy 2 for torch and pandas (#1911)
fixes #1764 Adding the comments from the Initial PR #1855 by @fkiraly The reason is that `numpy 2` added additional arguments to `__array_wrap__` which was interacting with `torch.Tensor.__array_wrap__` or `pandas.Series.__array_wrap__` that did not have said arguments on earlier versions, in `TorchNormalizer`. The warning can be avoided by explicit coercion to `torch` prior to mixed usage - avoiding mixed types across packages entirely. This also makes the coercions more explicit, enabling future refactors where we may want to move to more "clean" type assumptions instead of polymorphic union types.
1 parent cc6a3d7 commit e7a9c5f

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

pytorch_forecasting/data/encoders.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,17 +708,48 @@ def transform(
708708
target_scale = self.get_parameters().numpy()[None, :]
709709
center = target_scale[..., 0]
710710
scale = target_scale[..., 1]
711+
712+
if not isinstance(y, torch.Tensor):
713+
if isinstance(y, (pd.Series)):
714+
index = y.index
715+
pandas_dtype = y.dtype
716+
y = y.values
717+
y_was = "pandas"
718+
y = torch.as_tensor(y)
719+
elif isinstance(y, np.ndarray):
720+
y_was = "numpy"
721+
np_dtype = y.dtype
722+
try:
723+
y = torch.from_numpy(y)
724+
except TypeError:
725+
y = torch.as_tensor(y.astype(np.float32))
726+
else:
727+
y_was = "torch"
728+
torch_dtype = y.dtype
729+
if isinstance(center, np.ndarray):
730+
center = torch.from_numpy(center)
731+
if isinstance(scale, np.ndarray):
732+
scale = torch.from_numpy(scale)
711733
if y.ndim > center.ndim: # multiple batches -> expand size
712734
center = center.view(*center.size(), *(1,) * (y.ndim - center.ndim))
713735
scale = scale.view(*scale.size(), *(1,) * (y.ndim - scale.ndim))
714736

715-
# transform
716-
dtype = y.dtype
717737
y = (y - center) / scale
718-
try:
719-
y = y.astype(dtype)
720-
except AttributeError: # torch.Tensor has `.type()` instead of `.astype()`
721-
y = y.type(dtype)
738+
739+
if y_was == "numpy":
740+
numpy_data = y.numpy()
741+
if np_dtype.kind in "iu" and numpy_data.dtype.kind == "f":
742+
# Original was integer, but normalized data is float
743+
y = numpy_data.astype(np.float64)
744+
else:
745+
y = numpy_data.astype(np_dtype)
746+
elif y_was == "pandas":
747+
numpy_data = y.numpy()
748+
if pandas_dtype.kind in "iu" and numpy_data.dtype.kind == "f":
749+
pandas_dtype = np.float64
750+
y = pd.Series(numpy_data, index=index, dtype=pandas_dtype)
751+
else:
752+
y = y.type(torch_dtype)
722753

723754
# return with center and scale or without
724755
if return_norm:
@@ -761,6 +792,10 @@ def __call__(self, data: dict[str, torch.Tensor]) -> torch.Tensor:
761792
"""
762793
# ensure output dtype matches input dtype
763794
dtype = data["prediction"].dtype
795+
if isinstance(dtype, np.dtype):
796+
# convert the array into tensor if it is a numpy array
797+
data["prediction"] = torch.as_tensor(data["prediction"])
798+
dtype = data["prediction"].dtype
764799

765800
# inverse transformation with tensors
766801
norm = data["target_scale"]

0 commit comments

Comments
 (0)