Repository: pandas-dev/pandas

Issue:
.iloc with 1-element integer array behaves badly
There is an inconsistency in the returned (python) types when indexing .iloc with an integer array.  The result should always be a sequence (Series), but if the array contains exactly one index, it returns a scalar value:

``` python

>>> import pandas, numpy
>>> column = pandas.Series(numpy.arange(10))
>>> indices, = (column > 4).nonzero()
>>> column.iloc[indices]
5    5
6    6
7    7
8    8
9    9
dtype: int64
>>> indices, = (column == 5).nonzero()
>>> column.iloc[indices]
5
>>> indices, = (column == 99).nonzero()
>>> column.iloc[indices]
Series([], dtype: int64)
```

I am working around that using `numpy.atleast_1d`, but it's ugly.



Discussion:
looks like a buglet, not treating the `np.ndarray` input the same as a `list`, marking as a bug

```
In [21]: indices
Out[21]: array([5])

In [22]: type(indices)
Out[22]: numpy.ndarray

In [23]: column.iloc[list(indices)]
Out[23]: 
5    5
dtype: int64
```

fyi....this would be the preferred usage of what you are doing in any event

```
In [26]: column.loc[column==5]
Out[26]: 
5    5
dtype: int64
```

Thanks, but I have different use cases:  I am often using .diff().nonzero() in order to find indices where relevant parameters change (e.g. an error code, depending on some input parameters).  Otherwise, I am using boolean selections where possible.

np.....pretty trivial fix, want to do a PR?

I might have a look later (Monday), but I have to hurry and leave in < 5 minutes. ;-)

gr8.....will leave open for you!

@hmeine doing a PR for this?

Did not forget about it, but did not yet get around to it, either.  Is pandas/tests/test_indexing.py the right place for a regression test?  Here's a holiday today, so I have four family days.  Can't say yet whether that makes it harder or easier to find time for hacking. ;-)

test_indexing is good for this


Resolving patch:
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -1092,7 +1092,9 @@ def _getitem_axis(self, key, axis=0):
         else:
 
             if _is_list_like(key):
-                pass
+
+                # force an actual list
+                key = list(key)
             else:
                 key = self._convert_scalar_indexer(key, axis)
 


Test patch:
diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py
--- a/pandas/tests/test_indexing.py
+++ b/pandas/tests/test_indexing.py
@@ -333,8 +333,15 @@ def test_iloc_getitem_list_int(self):
 
         # list of ints
         self.check_result('list int', 'iloc', [0,1,2], 'ix', { 0 : [0,2,4], 1 : [0,3,6], 2: [0,4,8] }, typs = ['ints'])
+        self.check_result('list int', 'iloc', [2], 'ix', { 0 : [4], 1 : [6], 2: [8] }, typs = ['ints'])
         self.check_result('list int', 'iloc', [0,1,2], 'indexer', [0,1,2], typs = ['labels','mixed','ts','floats','empty'], fails = IndexError)
 
+        # array of ints
+        # (GH5006), make sure that a single indexer is returning the correct type
+        self.check_result('array int', 'iloc', np.array([0,1,2]), 'ix', { 0 : [0,2,4], 1 : [0,3,6], 2: [0,4,8] }, typs = ['ints'])
+        self.check_result('array int', 'iloc', np.array([2]), 'ix', { 0 : [4], 1 : [6], 2: [8] }, typs = ['ints'])
+        self.check_result('array int', 'iloc', np.array([0,1,2]), 'indexer', [0,1,2], typs = ['labels','mixed','ts','floats','empty'], fails = IndexError)
+
     def test_iloc_getitem_dups(self):
 
         # no dups in panel (bug?)