Skip to content

Commit ce20839

Browse files
author
MarcoGorelli
committed
BUG: 'Series.to_numpy(dtype=, na_value=)' behaves differently with 'pd.NA' and 'np.nan'
1 parent 3d6b365 commit ce20839

File tree

4 files changed

+18
-7
lines changed

4 files changed

+18
-7
lines changed

doc/source/whatsnew/v1.6.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ Indexing
216216
Missing
217217
^^^^^^^
218218
- Bug in :meth:`Index.equals` raising ``TypeError`` when :class:`Index` consists of tuples that contain ``NA`` (:issue:`48446`)
219+
- Bug when calling :meth:`Series.to_numpy` on a Series of ``object`` dtype containing ``pd.NA`` was raising even if ``na_value`` was valid (:issue:`48951`)
219220
-
220221

221222
MultiIndex

pandas/core/base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,14 @@ def to_numpy(
537537
f"to_numpy() got an unexpected keyword argument '{bad_keys}'"
538538
)
539539

540-
result = np.asarray(self._values, dtype=dtype)
541540
# TODO(GH-24345): Avoid potential double copy
542541
if copy or na_value is not lib.no_default:
543-
result = result.copy()
542+
result = self._values.copy()
544543
if na_value is not lib.no_default:
545544
result[np.asanyarray(self.isna())] = na_value
545+
result = np.asarray(result, dtype=dtype)
546+
else:
547+
result = np.asarray(self._values, dtype=dtype)
546548
return result
547549

548550
@property

pandas/core/internals/managers.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,10 +1745,12 @@ def as_array(
17451745
dtype=dtype,
17461746
na_value=na_value,
17471747
).reshape(blk.shape)
1748+
elif na_value is lib.no_default:
1749+
arr = np.asarray(blk.get_values(dtype))
17481750
else:
1749-
arr = np.asarray(blk.get_values())
1750-
if dtype:
1751-
arr = arr.astype(dtype, copy=False)
1751+
arr = np.empty(self.shape, dtype=dtype)
1752+
values = np.asarray(blk.get_values())
1753+
arr[:] = np.where(~isna(values), values, na_value)
17521754
else:
17531755
arr = self._interleave(dtype=dtype, na_value=na_value)
17541756
# The underlying data was copied within _interleave
@@ -1815,7 +1817,7 @@ def _interleave(
18151817
)
18161818
else:
18171819
arr = blk.get_values(dtype)
1818-
result[rl.indexer] = arr
1820+
result[rl.indexer] = np.where(~isna(arr), arr, na_value)
18191821
itemmask[rl.indexer] = 1
18201822

18211823
if not itemmask.all():

pandas/tests/base/test_conversion.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ def test_to_numpy_dtype(as_series):
398398
"values, dtype, na_value, expected",
399399
[
400400
([1, 2, None], "float64", 0, [1.0, 2.0, 0.0]),
401+
([1, 2, pd.NA, 4], "int32", 0, [1, 2, 0, 4]),
401402
(
402403
[Timestamp("2000"), Timestamp("2000"), pd.NaT],
403404
None,
@@ -411,7 +412,7 @@ def test_to_numpy_na_value_numpy_dtype(
411412
):
412413
obj = index_or_series(values)
413414
result = obj.to_numpy(dtype=dtype, na_value=na_value)
414-
expected = np.array(expected)
415+
expected = np.array(expected, dtype=dtype)
415416
tm.assert_numpy_array_equal(result, expected)
416417

417418

@@ -477,6 +478,7 @@ def test_to_numpy_kwargs_raises():
477478
{"a": [1, 2, 3], "b": [1, 2, None]},
478479
{"a": np.array([1, 2, 3]), "b": np.array([1, 2, np.nan])},
479480
{"a": pd.array([1, 2, 3]), "b": pd.array([1, 2, None])},
481+
{"a": np.array([1, 2, 3]), "b": np.array([1, 2, pd.NA])},
480482
],
481483
)
482484
@pytest.mark.parametrize("dtype, na_value", [(float, np.nan), (object, None)])
@@ -495,6 +497,10 @@ def test_to_numpy_dataframe_na_value(data, dtype, na_value):
495497
{"a": pd.array([1, 2, None])},
496498
np.array([[1.0], [2.0], [np.nan]], dtype=float),
497499
),
500+
(
501+
{"a": np.array([1, 2, pd.NA])},
502+
np.array([[1.0], [2.0], [np.nan]]),
503+
),
498504
(
499505
{"a": [1, 2, 3], "b": [1, 2, 3]},
500506
np.array([[1, 1], [2, 2], [3, 3]], dtype=float),

0 commit comments

Comments
 (0)