From 004507982ac654bbd56bb8afad9aba1d7b3c93a0 Mon Sep 17 00:00:00 2001 From: Pradyumna Date: Wed, 23 Sep 2015 22:50:38 +0530 Subject: [PATCH] issue #11119 --- pandas/core/frame.py | 4 +- pandas/core/indexing.py | 76 ++++++++++++++++++++------------------ pandas/tests/test_index.py | 6 +++ 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9e1eda4714734..fa16e72760faf 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1941,8 +1941,8 @@ def _getitem_array(self, key): warnings.warn("Boolean Series key will be reindexed to match " "DataFrame index.", UserWarning) elif len(key) != len(self.index): - raise ValueError('Item wrong length %d instead of %d.' % - (len(key), len(self.index))) + indexer = self.ix._convert_to_indexer(key, axis=1) + return self.take(indexer, axis=1, convert=True) # check_bool_indexer will throw exception if Series key cannot # be reindexed to match DataFrame rows key = check_bool_indexer(self.index, key) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 8b4528ef451ef..6b54b3266f79a 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1077,50 +1077,56 @@ def _convert_to_indexer(self, obj, axis=0, is_setter=False): return labels.get_locs(obj) elif is_list_like_indexer(obj): if is_bool_indexer(obj): - obj = check_bool_indexer(labels, obj) - inds, = obj.nonzero() - return inds - else: - if isinstance(obj, Index): - objarr = obj.values + if is_bool_indexer(list(labels)): + pass + elif len(obj) == self.obj.shape[axis]: + obj = check_bool_indexer(labels, obj) + inds, = obj.nonzero() + return inds else: - objarr = _asarray_tuplesafe(obj) + raise ValueError('Item wrong length %d instead of %d.' % + (len(obj), len(self.obj.index))) + + if isinstance(obj, Index): + objarr = obj.values + else: + objarr = _asarray_tuplesafe(obj) - # The index may want to handle a list indexer differently - # by returning an indexer or raising - indexer = labels._convert_list_indexer(objarr, kind=self.name) - if indexer is not None: - return indexer + # The index may want to handle a list indexer differently + # by returning an indexer or raising + indexer = labels._convert_list_indexer(objarr, kind=self.name) + if indexer is not None: + return indexer - # this is not the most robust, but... - if (isinstance(labels, MultiIndex) and - not isinstance(objarr[0], tuple)): - level = 0 - _, indexer = labels.reindex(objarr, level=level) + # this is not the most robust, but... + if (isinstance(labels, MultiIndex) and + not isinstance(objarr[0], tuple)): + level = 0 + _, indexer = labels.reindex(objarr, level=level) - # take all - if indexer is None: - indexer = np.arange(len(labels)) + # take all + if indexer is None: + indexer = np.arange(len(labels)) - check = labels.levels[0].get_indexer(objarr) - else: - level = None + check = labels.levels[0].get_indexer(objarr) + else: + level = None - # unique index - if labels.is_unique: - indexer = check = labels.get_indexer(objarr) + # unique index + if labels.is_unique: + indexer = check = labels.get_indexer(objarr) - # non-unique (dups) - else: - (indexer, - missing) = labels.get_indexer_non_unique(objarr) - check = indexer + # non-unique (dups) + else: + (indexer, + missing) = labels.get_indexer_non_unique(objarr) + check = indexer - mask = check == -1 - if mask.any(): - raise KeyError('%s not in index' % objarr[mask]) + mask = check == -1 + if mask.any(): + raise KeyError('%s not in index' % objarr[mask]) - return _values_from_object(indexer) + return _values_from_object(indexer) else: try: diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index 75daabe2dab67..2009123e03098 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -943,6 +943,12 @@ def test_booleanindex(self): subIndex = self.strIndex[list(boolIdx)] for i, val in enumerate(subIndex): self.assertEqual(subIndex.get_loc(val), i) + + def test_booleanLabel(self): + df = pd.DataFrame({True: [1,2,5,9], + False: [6,1,13,8]}) + self.assert_frame_equal(df[df[True]>3], df[2:]) + self.assert_frame_equal(df[[False,True]], df) def test_fancy(self): sl = self.strIndex[[1, 2, 3]]