Skip to content

Commit 34404be

Browse files
committed
BUG: Bug in setting with ix/loc and a mixed int/string index (GH4544)
1 parent 09b3c0a commit 34404be

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ Bug Fixes
520520
chunks of the same file. Now coerces to numerical type or raises warning. (:issue:`3866`)
521521
- Fix a bug where reshaping a ``Series`` to its own shape raised ``TypeError`` (:issue:`4554`)
522522
and other reshaping issues.
523+
- Bug in setting with ``ix/loc`` and a mixed int/string index (:issue:`4544`)
523524

524525
pandas 0.12.0
525526
-------------

pandas/core/indexing.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,25 @@ def _convert_to_indexer(self, obj, axis=0, is_setter=False):
783783
- No, prefer label-based indexing
784784
"""
785785
labels = self.obj._get_axis(axis)
786+
787+
# if we are a scalar indexer and not type correct raise
788+
obj = self._convert_scalar_indexer(obj, axis)
789+
790+
# see if we are positional in nature
786791
is_int_index = labels.is_integer()
792+
is_int_positional = com.is_integer(obj) and not is_int_index
787793

788-
if com.is_integer(obj) and not is_int_index:
794+
# if we are a label return me
795+
try:
796+
return labels.get_loc(obj)
797+
except (KeyError, TypeError):
798+
pass
799+
except (ValueError):
800+
if not is_int_positional:
801+
raise
802+
803+
# a positional
804+
if is_int_positional:
789805

790806
# if we are setting and its not a valid location
791807
# its an insert which fails by definition
@@ -795,11 +811,6 @@ def _convert_to_indexer(self, obj, axis=0, is_setter=False):
795811

796812
return obj
797813

798-
try:
799-
return labels.get_loc(obj)
800-
except (KeyError, TypeError):
801-
pass
802-
803814
if isinstance(obj, slice):
804815
return self._convert_slice_indexer(obj, axis)
805816

pandas/tests/test_indexing.py

+20
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,26 @@ def test_ix_assign_column_mixed(self):
10701070
df['b'].ix[[1,3]] = [100,-100]
10711071
assert_frame_equal(df,expected)
10721072

1073+
def test_ix_get_set_consistency(self):
1074+
1075+
# GH 4544
1076+
# ix/loc get/set not consistent when
1077+
# a mixed int/string index
1078+
df = DataFrame(np.arange(16).reshape((4, 4)),
1079+
columns=['a', 'b', 8, 'c'],
1080+
index=['e', 7, 'f', 'g'])
1081+
1082+
self.assert_(df.ix['e', 8] == 2)
1083+
self.assert_(df.loc['e', 8] == 2)
1084+
1085+
df.ix['e', 8] = 42
1086+
self.assert_(df.ix['e', 8] == 42)
1087+
self.assert_(df.loc['e', 8] == 42)
1088+
1089+
df.loc['e', 8] = 45
1090+
self.assert_(df.ix['e', 8] == 45)
1091+
self.assert_(df.loc['e', 8] == 45)
1092+
10731093
def test_iloc_mask(self):
10741094

10751095
# GH 3631, iloc with a mask (of a series) should raise

pandas/tests/test_series.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ def test_setitem_float_labels(self):
878878
tmp = s.copy()
879879

880880
s.ix[1] = 'zoo'
881-
tmp.values[1] = 'zoo'
881+
tmp.iloc[2] = 'zoo'
882882

883883
assert_series_equal(s, tmp)
884884

0 commit comments

Comments
 (0)