Skip to content

Commit

Permalink
BUG: fix regression in negative integer indexing from 0.7.x close #1888
Browse files Browse the repository at this point in the history
  • Loading branch information
wesm committed Sep 17, 2012
1 parent 68251c2 commit 325afdf
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
7 changes: 7 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pandas 0.9.0
- Add quoting option for DataFrame.to_csv (#1902)
- Indicate long column value truncation in DataFrame output with ... (#1854)
- DataFrame.dot will not do data alignment, and also work with Series (#1915)
- Add ``na`` option for missing data handling in some vectorized string
methods (#1689)

**API Changes**

Expand Down Expand Up @@ -169,6 +171,11 @@ pandas 0.9.0
- Raise Exception if set passed to Series constructor (#1913)
- Add TypeError when appending HDFStore table w/ wrong index type (#1881)
- Don't raise exception on empty inputs in EW functions (e.g. ewma) (#1900)
- Make asof work correctly with PeriodIndex (#1883)
- Fix extlinks in doc build
- Fill boolean DataFrame with NaN when calling shift (#1814)
- Fix setuptools bug causing pip not to Cythonize .pyx files sometimes
- Fix negative integer indexing regression in .ix from 0.7.x (#1888)

pandas 0.8.1
============
Expand Down
11 changes: 10 additions & 1 deletion pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,27 @@ def _reindex(keys, level=None):
inds, = np.asarray(key, dtype=bool).nonzero()
return self.obj.take(inds, axis=axis)
else:
if isinstance(key, Index):
was_index = isinstance(key, Index)
if was_index:
# want Index objects to pass through untouched
keyarr = key
else:
# asarray can be unsafe, NumPy strings are weird
keyarr = _asarray_tuplesafe(key)

if _is_integer_dtype(keyarr):
if labels.inferred_type != 'integer':
keyarr = np.where(keyarr < 0,
len(labels) + keyarr, keyarr)

if labels.inferred_type == 'mixed-integer':
indexer = labels.get_indexer(keyarr)
if (indexer >= 0).all():
self.obj.take(indexer, axis=axis)
else:
return self.obj.take(keyarr, axis=axis)
elif not labels.inferred_type == 'integer':

return self.obj.take(keyarr, axis=axis)

# this is not the most robust, but...
Expand Down Expand Up @@ -406,6 +412,9 @@ def _convert_to_indexer(self, obj, axis=0):

# If have integer labels, defer to label-based indexing
if _is_integer_dtype(objarr) and not is_int_index:
if labels.inferred_type != 'integer':
objarr = np.where(objarr < 0,
len(labels) + objarr, objarr)
return objarr

# this is not the most robust, but...
Expand Down
16 changes: 16 additions & 0 deletions pandas/tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,22 @@ def test_getitem_ix_mixed_integer(self):
expected = df.ix[Index([1, 10], dtype=object)]
assert_frame_equal(result, expected)

def test_getitem_setitem_ix_negative_integers(self):
result = self.frame.ix[:, -1]
assert_series_equal(result, self.frame['D'])

result = self.frame.ix[:, [-1]]
assert_frame_equal(result, self.frame[['D']])

result = self.frame.ix[:, [-1, -2]]
assert_frame_equal(result, self.frame[['D', 'C']])

self.frame.ix[:, [-1]] = 0
self.assert_((self.frame['D'] == 0).all())

df = DataFrame(np.random.randn(8, 4))
self.assert_(isnull(df.ix[:, [-1]].values).all())

def test_getattr(self):
tm.assert_series_equal(self.frame.A, self.frame['A'])
self.assertRaises(AttributeError, getattr, self.frame,
Expand Down

0 comments on commit 325afdf

Please sign in to comment.