diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index b462f0c6a8ffe..cb2e24437433c 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -14,7 +14,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ -- +- Fixed regression in taking NULL :class:`objects` from a :class:`DataFrame` causing a segmentation violation. These NULL values are created by :meth:`numpy.empty_like` (:issue:`46848`) - .. --------------------------------------------------------------------------- diff --git a/pandas/_libs/algos_take_helper.pxi.in b/pandas/_libs/algos_take_helper.pxi.in index 2a3858674af9e..4f96d5c0adc6c 100644 --- a/pandas/_libs/algos_take_helper.pxi.in +++ b/pandas/_libs/algos_take_helper.pxi.in @@ -147,8 +147,15 @@ def take_2d_axis0_{{name}}_{{dest}}(ndarray[{{c_type_in}}, ndim=2] values, {{if c_type_in == "uint8_t" and c_type_out == "object"}} out[i, j] = True if values[idx, j] > 0 else False {{else}} + {{if c_type_in == "object"}} # GH46848 + if values[idx][j] is None: + out[i, j] = None + else: + out[i, j] = values[idx, j] + {{else}} out[i, j] = values[idx, j] {{endif}} + {{endif}} @cython.wraparound(False) @@ -183,8 +190,15 @@ def take_2d_axis1_{{name}}_{{dest}}(ndarray[{{c_type_in}}, ndim=2] values, {{if c_type_in == "uint8_t" and c_type_out == "object"}} out[i, j] = True if values[i, idx] > 0 else False {{else}} + {{if c_type_in == "object"}} # GH46848 + if values[i][idx] is None: + out[i, j] = None + else: + out[i, j] = values[i, idx] + {{else}} out[i, j] = values[i, idx] {{endif}} + {{endif}} @cython.wraparound(False) diff --git a/pandas/tests/test_take.py b/pandas/tests/test_take.py index f0737f7dc4cce..036710dce74fd 100644 --- a/pandas/tests/test_take.py +++ b/pandas/tests/test_take.py @@ -6,8 +6,10 @@ from pandas._libs import iNaT +import pandas as pd import pandas._testing as tm import pandas.core.algorithms as algos +from pandas.core.array_algos.take import _take_nd_ndarray @pytest.fixture(params=[True, False]) @@ -332,3 +334,25 @@ def test_take_coerces_list(self): result = algos.take(arr, [0, 0]) expected = np.array([1, 1]) tm.assert_numpy_array_equal(result, expected) + + +class TestTakeNumpyNull: + # GH 46848 + + def test_take_2d_axis0_object_object(self): + arr = np.array([[None]], dtype=object) + indexer = np.array([0]) + axis = 1 + fill_value = None + allow_fill = False + + result = _take_nd_ndarray(arr, indexer, axis, fill_value, allow_fill) + assert result == [[None]] + arr2 = np.empty_like(arr) + result2 = _take_nd_ndarray(arr2, indexer, axis, fill_value, allow_fill) + assert result2 == [[None]] + + def test_take_2d_axis1_object_object(self): + df = pd.DataFrame(np.empty((1, 1), dtype=object)) + df[0] = np.empty_like(df[0]) + df[[0]]