Repository: pandas-dev/pandas

Issue:
Series.drop regression and unexpected behaviour
On 0.12 stable this works:

```
>>> s = pandas.Series([1,1,2],index=["one","one","two"])
>>> s.drop(["one"])
two    2
dtype: int64
```

but a singleton silently fails:

```
>>> s.drop("one")
one    1
one    1
two    2
dtype: int64
```

except when index is unique:

```
>>> s = pandas.Series([1,2],index=["one","two"])
>>> s.drop("one")
two    2
dtype: int64
```

according to the docs, the input to drop should be array like, so i'm not sure this should be permissible.

On head, with unique index, it matches, but with non-unique:

```
>>> pandas.__version__
'0.12.0-892-g6830600'
>>> s = pandas.Series([1,1,2],index=["one","one","two"])
>>> s2 = s.drop(["one"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pandas/core/generic.py", line 1133, in drop
    return self.ix[tuple(slicer)]
  File "pandas/core/indexing.py", line 53, in __getitem__
    return self._getitem_tuple(key)
  File "pandas/core/indexing.py", line 558, in _getitem_tuple
    return self._multi_take(tup)
  File "pandas/core/indexing.py", line 598, in _multi_take
    raise self._exception
KeyError
```



Discussion:

Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -672,9 +672,9 @@ def to_dict(self, outtype='dict'):
             raise ValueError("outtype %s not understood" % outtype)
 
     def to_gbq(self, destination_table, schema=None, col_order=None, if_exists='fail', **kwargs):
-        """Write a DataFrame to a Google BigQuery table. 
-        
-        If the table exists, the DataFrame will be appended. If not, a new table 
+        """Write a DataFrame to a Google BigQuery table.
+
+        If the table exists, the DataFrame will be appended. If not, a new table
         will be created, in which case the schema will have to be specified. By default,
         rows will be written in the order they appear in the DataFrame, though
         the user may specify an alternative order.
@@ -2233,33 +2233,6 @@ def rename(self, index=None, columns=None, **kwargs):
         return super(DataFrame, self).rename(index=index, columns=columns,
                                              **kwargs)
 
-    def reindex_like(self, other, method=None, copy=True, limit=None,
-                     fill_value=NA):
-        """
-        Reindex DataFrame to match indices of another DataFrame, optionally
-        with filling logic
-
-        Parameters
-        ----------
-        other : DataFrame
-        method : string or None
-        copy : boolean, default True
-        limit : int, default None
-            Maximum size gap to forward or backward fill
-
-        Notes
-        -----
-        Like calling s.reindex(index=other.index, columns=other.columns,
-                               method=...)
-
-        Returns
-        -------
-        reindexed : DataFrame
-        """
-        return self.reindex(index=other.index, columns=other.columns,
-                            method=method, copy=copy, limit=limit,
-                            fill_value=fill_value)
-
     def set_index(self, keys, drop=True, append=False, inplace=False,
                   verify_integrity=False):
         """
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -1103,6 +1103,8 @@ def drop(self, labels, axis=0, level=None):
         """
         axis_name = self._get_axis_name(axis)
         axis, axis_ = self._get_axis(axis), axis
+        if not is_list_like(labels):
+            labels = [ labels ]
 
         if axis.is_unique:
             if level is not None:
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -581,9 +581,11 @@ def _multi_take_opportunity(self, tup):
             return False
 
         # just too complicated
-        for ax in self.obj._data.axes:
+        for indexer, ax in zip(tup,self.obj._data.axes):
             if isinstance(ax, MultiIndex):
                 return False
+            elif com._is_bool_indexer(indexer):
+                return False
 
         return True
 


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -3175,9 +3175,11 @@ def check(result, expected=None):
 
         # drop
         df = DataFrame([[1,5,7.],[1,5,7.],[1,5,7.]],columns=['bar','a','a'])
-        df = df.drop(['a'],axis=1)
+        result = df.drop(['a'],axis=1)
         expected = DataFrame([[1],[1],[1]],columns=['bar'])
-        check(df,expected)
+        check(result,expected)
+        result = df.drop('a',axis=1)
+        check(result,expected)
 
         # describe
         df = DataFrame([[1,1,1],[2,2,2],[3,3,3]],columns=['bar','a','a'],dtype='float64')
diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py
--- a/pandas/tests/test_series.py
+++ b/pandas/tests/test_series.py
@@ -1415,6 +1415,31 @@ def test_mask(self):
         rs = s.where(cond, np.nan)
         assert_series_equal(rs, s.mask(~cond))
 
+    def test_drop(self):
+
+        # unique
+        s = Series([1,2],index=['one','two'])
+        expected = Series([1],index=['one'])
+        result = s.drop(['two'])
+        assert_series_equal(result,expected)
+        result = s.drop('two')
+        assert_series_equal(result,expected)
+
+        # non-unique
+        # GH 5248
+        s = Series([1,1,2],index=['one','two','one'])
+        expected = Series([1,2],index=['one','one'])
+        result = s.drop(['two'])
+        assert_series_equal(result,expected)
+        result = s.drop('two')
+        assert_series_equal(result,expected)
+
+        expected = Series([1],index=['two'])
+        result = s.drop(['one'])
+        assert_series_equal(result,expected)
+        result = s.drop('one')
+        assert_series_equal(result,expected)
+
     def test_ix_setitem(self):
         inds = self.series.index[[3, 4, 7]]