@@ -168,24 +168,35 @@ def _to_numpy(data: Any) -> np.ndarray:
168
168
"date64[ms][pyarrow]" : "datetime64[ms]" ,
169
169
}
170
170
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.
171
180
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 )
184
194
185
195
# Check if a np.object_ array can be converted to np.str_.
186
196
if array .dtype == np .object_ :
187
197
with contextlib .suppress (TypeError , ValueError ):
188
198
return np .ascontiguousarray (array , dtype = np .str_ )
199
+
189
200
return array
190
201
191
202
0 commit comments