Skip to content

Commit 22ac90b

Browse files
rhshadrachpmhatre1
authored andcommitted
REGR: DataFrame.transpose resulting in not contiguous data on nullable EAs (pandas-dev#57474)
1 parent 258d31c commit 22ac90b

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

doc/source/whatsnew/v2.2.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Fixed regressions
3232
- Fixed regression in :meth:`DataFrame.to_dict` with ``orient='list'`` and datetime or timedelta types returning integers (:issue:`54824`)
3333
- Fixed regression in :meth:`DataFrame.to_json` converting nullable integers to floats (:issue:`57224`)
3434
- Fixed regression in :meth:`DataFrame.to_sql` when ``method="multi"`` is passed and the dialect type is not Oracle (:issue:`57310`)
35+
- Fixed regression in :meth:`DataFrame.transpose` with nullable extension dtypes not having F-contiguous data potentially causing exceptions when used (:issue:`57315`)
3536
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` ignoring the ``skipna`` argument (:issue:`57040`)
3637
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` where values containing the minimum or maximum value for the dtype could produce incorrect results (:issue:`57040`)
3738
- Fixed regression in :meth:`ExtensionArray.to_numpy` raising for non-numeric masked dtypes (:issue:`56991`)

pandas/core/arrays/masked.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -1651,13 +1651,24 @@ def transpose_homogeneous_masked_arrays(
16511651
same dtype. The caller is responsible for ensuring validity of input data.
16521652
"""
16531653
masked_arrays = list(masked_arrays)
1654+
dtype = masked_arrays[0].dtype
1655+
16541656
values = [arr._data.reshape(1, -1) for arr in masked_arrays]
1655-
transposed_values = np.concatenate(values, axis=0)
1657+
transposed_values = np.concatenate(
1658+
values,
1659+
axis=0,
1660+
out=np.empty(
1661+
(len(masked_arrays), len(masked_arrays[0])),
1662+
order="F",
1663+
dtype=dtype.numpy_dtype,
1664+
),
1665+
)
16561666

16571667
masks = [arr._mask.reshape(1, -1) for arr in masked_arrays]
1658-
transposed_masks = np.concatenate(masks, axis=0)
1668+
transposed_masks = np.concatenate(
1669+
masks, axis=0, out=np.empty_like(transposed_values, dtype=bool)
1670+
)
16591671

1660-
dtype = masked_arrays[0].dtype
16611672
arr_type = dtype.construct_array_type()
16621673
transposed_arrays: list[BaseMaskedArray] = []
16631674
for i in range(transposed_values.shape[1]):

pandas/tests/frame/methods/test_transpose.py

+17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22
import pytest
33

4+
import pandas as pd
45
from pandas import (
56
DataFrame,
67
DatetimeIndex,
@@ -179,3 +180,19 @@ def test_transpose_not_inferring_dt_mixed_blocks(self):
179180
dtype=object,
180181
)
181182
tm.assert_frame_equal(result, expected)
183+
184+
@pytest.mark.parametrize("dtype1", ["Int64", "Float64"])
185+
@pytest.mark.parametrize("dtype2", ["Int64", "Float64"])
186+
def test_transpose(self, dtype1, dtype2):
187+
# GH#57315 - transpose should have F contiguous blocks
188+
df = DataFrame(
189+
{
190+
"a": pd.array([1, 1, 2], dtype=dtype1),
191+
"b": pd.array([3, 4, 5], dtype=dtype2),
192+
}
193+
)
194+
result = df.T
195+
for blk in result._mgr.blocks:
196+
# When dtypes are unequal, we get NumPy object array
197+
data = blk.values._data if dtype1 == dtype2 else blk.values
198+
assert data.flags["F_CONTIGUOUS"]

0 commit comments

Comments
 (0)