Skip to content

Commit 0b4ebc7

Browse files
committed
ENH: Add sort_columns parameter to combine_first
1 parent 6333c3b commit 0b4ebc7

File tree

3 files changed

+20
-13
lines changed

3 files changed

+20
-13
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ including other versions of pandas.
1313

1414
Enhancements
1515
~~~~~~~~~~~~
16+
- Added a ``sort_columns`` parameter to :meth:`DataFrame.combine_first` to allow
17+
control over whether the result's column order should follow the original
18+
DataFrame's order or be sorted lexicographically. ([#60427](https://github.com/pandas-dev/pandas/issues/60427))
19+
1620

1721
.. _whatsnew_300.enhancements.enhancement1:
1822

pandas/core/frame.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8712,7 +8712,9 @@ def combine(
87128712
frame_result = self._constructor(result, index=new_index, columns=new_columns)
87138713
return frame_result.__finalize__(self, method="combine")
87148714

8715-
def combine_first(self, other: DataFrame, sort_columns=True) -> DataFrame:
8715+
def combine_first(
8716+
self, other: DataFrame, *, sort_columns: bool = True
8717+
) -> DataFrame:
87168718
"""
87178719
Update null elements with value in the same location in `other`.
87188720
@@ -8789,7 +8791,7 @@ def combiner(x: Series, y: Series):
87898791
return y_values
87908792

87918793
return expressions.where(mask, y_values, x_values)
8792-
8794+
87938795
all_columns = self.columns.union(other.columns)
87948796

87958797
if len(other) == 0:
@@ -8808,13 +8810,11 @@ def combiner(x: Series, y: Series):
88088810

88098811
if dtypes:
88108812
combined = combined.astype(dtypes)
8811-
8813+
88128814
combined = combined.reindex(columns=all_columns, fill_value=None)
88138815

88148816
if not sort_columns:
88158817
combined = combined[self.columns]
8816-
8817-
88188818

88198819
return combined.__finalize__(self, method="combine_first")
88208820

@@ -10543,9 +10543,11 @@ def _append(
1054310543

1054410544
index = Index(
1054510545
[other.name],
10546-
name=self.index.names
10547-
if isinstance(self.index, MultiIndex)
10548-
else self.index.name,
10546+
name=(
10547+
self.index.names
10548+
if isinstance(self.index, MultiIndex)
10549+
else self.index.name
10550+
),
1054910551
)
1055010552
row_df = other.to_frame().T
1055110553
# infer_objects is needed for

pandas/tests/frame/methods/test_combine_first.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -561,10 +561,11 @@ def test_combine_first_empty_columns():
561561
expected = DataFrame(columns=["a", "b", "c"])
562562
tm.assert_frame_equal(result, expected)
563563

564+
564565
def test_combine_first_column_order():
565-
df1 = pd.DataFrame({"B": [1, 2], "A": [3, 4]})
566-
df2 = pd.DataFrame({"A": [5]}, index=[1])
566+
df1 = DataFrame({"B": [1, 2], "A": [3, 4]})
567+
df2 = DataFrame({"A": [5]}, index=[1])
567568

568-
result = df1.combine_first(df2,sort_columns=False)
569-
expected = pd.DataFrame({"B": [1, 2], "A": [3, 4]})
570-
pd.testing.assert_frame_equal(result, expected)
569+
result = df1.combine_first(df2, sort_columns=False)
570+
expected = DataFrame({"B": [1, 2], "A": [3, 4]})
571+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)