diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index d8a5855d05dfd..3807fdd47b54f 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -221,7 +221,7 @@ def to_numeric(arg, errors="raise", downcast=None): from pandas.core.arrays import FloatingArray, IntegerArray klass = IntegerArray if is_integer_dtype(data.dtype) else FloatingArray - values = klass(data, mask) + values = klass(data, mask.copy()) if is_series: return arg._constructor(values, index=arg.index, name=arg.name) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index 80446e464985c..d5b4bda35ca2b 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -764,3 +764,16 @@ def test_downcast_nullable_numeric(data, input_dtype, downcast, expected_dtype): result = pd.to_numeric(arr, downcast=downcast) expected = pd.array(data, dtype=expected_dtype) tm.assert_extension_array_equal(result, expected) + + +def test_downcast_nullable_mask_is_copied(): + # GH38974 + + arr = pd.array([1, 2, pd.NA], dtype="Int64") + + result = pd.to_numeric(arr, downcast="integer") + expected = pd.array([1, 2, pd.NA], dtype="Int8") + tm.assert_extension_array_equal(result, expected) + + arr[1] = pd.NA # should not modify result + tm.assert_extension_array_equal(result, expected)