From 6d55c78d3f051c00153d37759faf9c60bf849224 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 23 Oct 2017 14:43:55 +0200 Subject: [PATCH 1/4] REF/INT: preserve block type in joining when only having a single block --- pandas/core/internals.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index f6c5ecbca81ef..524dc77940316 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -5182,7 +5182,15 @@ def concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy): for placement, join_units in concat_plan: - if is_uniform_join_units(join_units): + if len(join_units) == 1 and not join_units[0].indexers: + b = join_units[0].block + values = b.values + if copy and values.base is not None: + values = values.copy() + elif not copy: + values = values.view() + b = b.make_block_same_class(values, placement=placement) + elif is_uniform_join_units(join_units): b = join_units[0].block.concat_same_type( [ju.block for ju in join_units], placement=placement) else: From 29135e15edae0ef776142d0c589cd5674eae6f59 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 24 Oct 2017 09:33:21 +0200 Subject: [PATCH 2/4] add test --- pandas/tests/internals/test_external_block.py | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/pandas/tests/internals/test_external_block.py b/pandas/tests/internals/test_external_block.py index d98b293ed8daa..729ee0093b6dc 100644 --- a/pandas/tests/internals/test_external_block.py +++ b/pandas/tests/internals/test_external_block.py @@ -7,6 +7,8 @@ from pandas.core.internals import ( Block, BlockManager, SingleBlockManager, NonConsolidatableMixIn) +import pytest + class CustomBlock(NonConsolidatableMixIn, Block): @@ -25,6 +27,17 @@ def concat_same_type(self, to_concat, placement=None): values, placement=placement or slice(0, len(values), 1)) +@pytest.fixture +def df(): + df1 = pd.DataFrame({'a': [1, 2, 3]}) + blocks = df1._data.blocks + values = np.arange(3, dtype='int64') + custom_block = CustomBlock(values, placement=slice(1, 2)) + blocks = blocks + (custom_block,) + block_manager = BlockManager(blocks, [pd.Index(['a', 'b']), df1.index]) + return pd.DataFrame(block_manager) + + def test_custom_repr(): values = np.arange(3, dtype='int64') @@ -51,14 +64,14 @@ def test_concat_series(): assert isinstance(res._data.blocks[0], CustomBlock) -def test_concat_dataframe(): +def test_concat_dataframe(df): # GH17728 - df = pd.DataFrame({'a': [1, 2, 3]}) - blocks = df._data.blocks - values = np.arange(3, dtype='int64') - custom_block = CustomBlock(values, placement=slice(1, 2)) - blocks = blocks + (custom_block, ) - block_manager = BlockManager(blocks, [pd.Index(['a', 'b']), df.index]) - df = pd.DataFrame(block_manager) res = pd.concat([df, df]) assert isinstance(res._data.blocks[1], CustomBlock) + + +def test_concat_axis1(df): + # GH17954 + df2 = pd.DataFrame({'c': [.1, .2, .3]}) + res = pd.concat([df, df2], axis=1) + assert isinstance(res._data.blocks[1], CustomBlock) From 2125ac09726cfc720def79e836398ed04ecae04a Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 24 Oct 2017 10:10:22 +0200 Subject: [PATCH 3/4] remove checking of values.base --- pandas/core/internals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 524dc77940316..829784fd9790d 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -5185,7 +5185,7 @@ def concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy): if len(join_units) == 1 and not join_units[0].indexers: b = join_units[0].block values = b.values - if copy and values.base is not None: + if copy: # and values.base is not None: values = values.copy() elif not copy: values = values.view() From 3cee1aa7ff76433ef596166b469208362b0ef286 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 27 Oct 2017 11:49:09 +0200 Subject: [PATCH 4/4] clean-up comment --- pandas/core/internals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 829784fd9790d..045580d393b26 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -5185,7 +5185,7 @@ def concatenate_block_managers(mgrs_indexers, axes, concat_axis, copy): if len(join_units) == 1 and not join_units[0].indexers: b = join_units[0].block values = b.values - if copy: # and values.base is not None: + if copy: values = values.copy() elif not copy: values = values.view()