From f5c027dfc6fd5e1bd5fd0549fedc97650ff2aa05 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 20 Jul 2018 11:11:28 -0700 Subject: [PATCH 1/2] simplify BlockPlacement.iadd --- pandas/_libs/internals.pyx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index 2179999859dbb..508492b175ca2 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -29,6 +29,8 @@ cdef class BlockPlacement: def __init__(self, val): cdef slice slc + self._as_slice = None + self._as_array = None self._has_slice = False self._has_array = False @@ -141,6 +143,7 @@ cdef class BlockPlacement: other_int = other if other_int == 0: + # BlockPlacement is treated as immutable return self start, stop, step, l = slice_get_indices_ex(s) @@ -152,23 +155,18 @@ cdef class BlockPlacement: raise ValueError("iadd causes length change") if stop < 0: - self._as_slice = slice(start, None, step) + val = slice(start, None, step) else: - self._as_slice = slice(start, stop, step) + val = slice(start, stop, step) - self._has_array = False - self._as_array = None + return BlockPlacement(val) else: newarr = self.as_array + other if (newarr < 0).any(): raise ValueError("iadd causes length change") - self._as_array = newarr - self._has_array = True - self._has_slice = False - self._as_slice = None - - return self + val = newarr + return BlockPlacement(val) cdef BlockPlacement copy(self): cdef slice s = self._ensure_has_slice() @@ -178,7 +176,7 @@ cdef class BlockPlacement: return BlockPlacement(self._as_array) def add(self, other): - return self.copy().iadd(other) + return self.iadd(other) def sub(self, other): return self.add(-other) From 05873dcfbc188191650d0f2f54cf4e2297fb47e3 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 20 Jul 2018 12:07:02 -0700 Subject: [PATCH 2/2] Remove BlockPlacement.copy, BlockManager.get_scalar, _is_indexed_like --- pandas/_libs/internals.pyx | 7 ----- pandas/core/internals.py | 39 +++--------------------- pandas/tests/internals/test_internals.py | 20 ------------ 3 files changed, 5 insertions(+), 61 deletions(-) diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index 508492b175ca2..0795090ffb18b 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -168,13 +168,6 @@ cdef class BlockPlacement: val = newarr return BlockPlacement(val) - cdef BlockPlacement copy(self): - cdef slice s = self._ensure_has_slice() - if s is not None: - return BlockPlacement(s) - else: - return BlockPlacement(self._as_array) - def add(self, other): return self.iadd(other) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 5a5418dcc1e7f..10719c13f7420 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -3249,7 +3249,6 @@ class BlockManager(PandasObject): get_slice(slice_like, axis) get(label) iget(loc) - get_scalar(label_tup) take(indexer, axis) reindex_axis(new_labels, axis) @@ -4160,21 +4159,6 @@ def iget(self, i, fastpath=True): ndim=1)], self.axes[1]) - def get_scalar(self, tup): - """ - Retrieve single item - """ - full_loc = [ax.get_loc(x) for ax, x in zip(self.axes, tup)] - blk = self.blocks[self._blknos[full_loc[0]]] - values = blk.values - - # FIXME: this may return non-upcasted types? - if values.ndim == 1: - return values[full_loc[1]] - - full_loc[0] = self._blklocs[full_loc[0]] - return values[tuple(full_loc)] - def delete(self, item): """ Delete selected item (items if non-unique) in-place. @@ -4547,9 +4531,9 @@ def take(self, indexer, axis=1, verify=True, convert=True): axis=axis, allow_dups=True) def merge(self, other, lsuffix='', rsuffix=''): - if not self._is_indexed_like(other): - raise AssertionError('Must have same axes to merge managers') - + # We assume at this point that the axes of self and other match. + # This is only called from Panel.join, which reindexes prior + # to calling to ensure this assumption holds. l, r = items_overlap_with_suffix(left=self.items, lsuffix=lsuffix, right=other.items, rsuffix=rsuffix) new_items = _concat_indexes([l, r]) @@ -4567,19 +4551,6 @@ def merge(self, other, lsuffix='', rsuffix=''): return self.__class__(_consolidate(new_blocks), new_axes) - def _is_indexed_like(self, other): - """ - Check all axes except items - """ - if self.ndim != other.ndim: - raise AssertionError( - 'Number of dimensions must agree got {ndim} and ' - '{oth_ndim}'.format(ndim=self.ndim, oth_ndim=other.ndim)) - for ax, oax in zip(self.axes[1:], other.axes[1:]): - if not ax.equals(oax): - return False - return True - def equals(self, other): self_axes, other_axes = self.axes, other.axes if len(self_axes) != len(other_axes): @@ -4712,11 +4683,11 @@ def get_slice(self, slobj, axis=0): raise IndexError("Requested axis not found in manager") return self.__class__(self._block._slice(slobj), - self.index[slobj], fastpath=True) + self.items[slobj], fastpath=True) @property def index(self): - return self.axes[0] + return self.items def convert(self, **kwargs): """ convert the whole block as one """ diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py index 7fbf7ec05e91e..270550141305b 100644 --- a/pandas/tests/internals/test_internals.py +++ b/pandas/tests/internals/test_internals.py @@ -328,17 +328,6 @@ def test_is_mixed_dtype(self): assert create_mgr('a,b:f8; c,d: f4').is_mixed_type assert create_mgr('a,b:f8; c,d: object').is_mixed_type - def test_is_indexed_like(self): - mgr1 = create_mgr('a,b: f8') - mgr2 = create_mgr('a:i8; b:bool') - mgr3 = create_mgr('a,b,c: f8') - assert mgr1._is_indexed_like(mgr1) - assert mgr1._is_indexed_like(mgr2) - assert mgr1._is_indexed_like(mgr3) - - assert not mgr1._is_indexed_like(mgr1.get_slice( - slice(-1), axis=1)) - def test_duplicate_ref_loc_failure(self): tmp_mgr = create_mgr('a:bool; a: f8') @@ -395,15 +384,6 @@ def test_categorical_block_pickle(self): smgr2 = tm.round_trip_pickle(smgr) assert_series_equal(Series(smgr), Series(smgr2)) - def test_get_scalar(self, mgr): - for item in mgr.items: - for i, index in enumerate(mgr.axes[1]): - res = mgr.get_scalar((item, index)) - exp = mgr.get(item, fastpath=False)[i] - assert res == exp - exp = mgr.get(item).internal_values()[i] - assert res == exp - def test_get(self): cols = Index(list('abc')) values = np.random.rand(3, 3)