Skip to content

Commit 0aa73e6

Browse files
committed
Improve the workaround for handling pandas null dtypes in pandas<=2.1
1 parent ead78bf commit 0aa73e6

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

pygmt/clib/conversion.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,35 @@ def _to_numpy(data: Any) -> np.ndarray:
168168
"date64[ms][pyarrow]": "datetime64[ms]",
169169
}
170170

171+
# The expected numpy dtype for the result numpy array, but can be None.
172+
dtype = dtypes.get(str(getattr(data, "dtype", getattr(data, "type", ""))))
173+
174+
# pandas numeric dtypes were converted to np.object_ dtype prior pandas 2.2, and are
175+
# converted to suitable NumPy dtypes since pandas 2.2. Refer to the following link
176+
# for details: https://pandas.pydata.org/docs/whatsnew/v2.2.0.html#to-numpy-for-numpy-nullable-and-arrow-types-converts-to-suitable-numpy-dtype
177+
#
178+
# Workarounds for pandas < 2.2. Following SPEC 0, pandas 2.1 should be dropped in
179+
# 2025 Q3, so it's likely we can remove the workaround in PyGMT v0.17.0.
171180
if (
172-
hasattr(data, "isna")
173-
and data.isna().any()
174-
and Version(pd.__version__) < Version("2.2")
175-
):
176-
# Workaround for dealing with pd.NA with pandas < 2.2.
177-
# Bug report at: https://github.com/GenericMappingTools/pygmt/issues/2844
178-
# Following SPEC0, pandas 2.1 will be dropped in 2025 Q3, so it's likely
179-
# we can remove the workaround in PyGMT v0.17.0.
180-
array = np.ascontiguousarray(data.astype(float))
181-
else:
182-
vec_dtype = str(getattr(data, "dtype", getattr(data, "type", "")))
183-
array = np.ascontiguousarray(data, dtype=dtypes.get(vec_dtype))
181+
Version(pd.__version__) < Version("2.2") # pandas < 2.2 only.
182+
and hasattr(data, "dtype") # NumPy array or pandas objects only.
183+
and hasattr(data.dtype, "numpy_dtype") # pandas dtypes only.
184+
and data.dtype.kind in "iuf" # Numeric dtypes only.
185+
): # pandas Series/Index with pandas nullable numeric dtypes.
186+
dtype = data.dtype.numpy_dtype # The expected numpy dtype.
187+
if getattr(data, "hasnans", False):
188+
if data.dtype.kind in "iu":
189+
# Integers with missing values are converted to float64.
190+
dtype = np.float64
191+
data = data.to_numpy(na_value=np.nan)
192+
193+
array = np.ascontiguousarray(data, dtype=dtype)
184194

185195
# Check if a np.object_ array can be converted to np.str_.
186196
if array.dtype == np.object_:
187197
with contextlib.suppress(TypeError, ValueError):
188198
return np.ascontiguousarray(array, dtype=np.str_)
199+
189200
return array
190201

191202

0 commit comments

Comments
 (0)