From c230f2e564b225633e94a22b92ed382a99bd501b Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 27 Apr 2018 11:42:03 +0200 Subject: [PATCH 1/3] BUG: concat of Series of EA and other dtype fails --- pandas/core/dtypes/concat.py | 4 ++-- pandas/tests/extension/base/reshaping.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/core/dtypes/concat.py b/pandas/core/dtypes/concat.py index 377ef7ad7e4f8..335adebe17f88 100644 --- a/pandas/core/dtypes/concat.py +++ b/pandas/core/dtypes/concat.py @@ -175,8 +175,8 @@ def is_nonempty(x): return _concat_sparse(to_concat, axis=axis, typs=typs) extensions = [is_extension_array_dtype(x) for x in to_concat] - if any(extensions): - to_concat = [np.atleast_2d(x.astype('object')) for x in to_concat] + if any(extensions) and axis == 1: + to_concat = [np.atleast_2d(x.astype('object')) for x in to_concat] if not nonempty: # we have all empties, but may need to coerce the result dtype to diff --git a/pandas/tests/extension/base/reshaping.py b/pandas/tests/extension/base/reshaping.py index cc78321dea7af..b3cd48e69a32a 100644 --- a/pandas/tests/extension/base/reshaping.py +++ b/pandas/tests/extension/base/reshaping.py @@ -64,6 +64,11 @@ def test_concat_mixed_dtypes(self, data): expected = pd.concat([df1.astype('object'), df2.astype('object')]) self.assert_frame_equal(result, expected) + result = pd.concat([df1['A'], df2['A']]) + expected = pd.concat([df1['A'].astype('object'), + df2['A'].astype('object')]) + self.assert_series_equal(result, expected) + def test_align(self, data, na_value): a = data[:3] b = data[2:5] From 0dfa346f76557bf03f04b2b3b7ddbeda89889ec7 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sat, 28 Apr 2018 14:09:05 +0200 Subject: [PATCH 2/3] fix indent --- pandas/core/dtypes/concat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/dtypes/concat.py b/pandas/core/dtypes/concat.py index 335adebe17f88..4aa74cdbbc2c0 100644 --- a/pandas/core/dtypes/concat.py +++ b/pandas/core/dtypes/concat.py @@ -176,7 +176,7 @@ def is_nonempty(x): extensions = [is_extension_array_dtype(x) for x in to_concat] if any(extensions) and axis == 1: - to_concat = [np.atleast_2d(x.astype('object')) for x in to_concat] + to_concat = [np.atleast_2d(x.astype('object')) for x in to_concat] if not nonempty: # we have all empties, but may need to coerce the result dtype to From 964a5ffecf7e5df68ea951896ef809ffcd5b22c7 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sat, 28 Apr 2018 14:19:05 +0200 Subject: [PATCH 3/3] add test for concat axis=1 --- pandas/tests/extension/base/reshaping.py | 20 +++++++++++++++++++ .../extension/category/test_categorical.py | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/pandas/tests/extension/base/reshaping.py b/pandas/tests/extension/base/reshaping.py index b3cd48e69a32a..fe920a47ab740 100644 --- a/pandas/tests/extension/base/reshaping.py +++ b/pandas/tests/extension/base/reshaping.py @@ -69,6 +69,26 @@ def test_concat_mixed_dtypes(self, data): df2['A'].astype('object')]) self.assert_series_equal(result, expected) + def test_concat_columns(self, data, na_value): + df1 = pd.DataFrame({'A': data[:3]}) + df2 = pd.DataFrame({'B': [1, 2, 3]}) + + expected = pd.DataFrame({'A': data[:3], 'B': [1, 2, 3]}) + result = pd.concat([df1, df2], axis=1) + self.assert_frame_equal(result, expected) + result = pd.concat([df1['A'], df2['B']], axis=1) + self.assert_frame_equal(result, expected) + + # non-aligned + df2 = pd.DataFrame({'B': [1, 2, 3]}, index=[1, 2, 3]) + expected = pd.DataFrame({ + 'A': data._from_sequence(list(data[:3]) + [na_value]), + 'B': [np.nan, 1, 2, 3]}) + result = pd.concat([df1, df2], axis=1) + self.assert_frame_equal(result, expected) + result = pd.concat([df1['A'], df2['B']], axis=1) + self.assert_frame_equal(result, expected) + def test_align(self, data, na_value): a = data[:3] b = data[2:5] diff --git a/pandas/tests/extension/category/test_categorical.py b/pandas/tests/extension/category/test_categorical.py index 6ebe700f13be0..579dad78579a0 100644 --- a/pandas/tests/extension/category/test_categorical.py +++ b/pandas/tests/extension/category/test_categorical.py @@ -67,6 +67,10 @@ class TestConstructors(base.BaseConstructorsTests): class TestReshaping(base.BaseReshapingTests): + @pytest.mark.skip(reason="Unobserved categories preseved in concat.") + def test_concat_columns(self, data, na_value): + pass + @pytest.mark.skip(reason="Unobserved categories preseved in concat.") def test_align(self, data, na_value): pass