Skip to content

Commit 5d1af2f

Browse files
mariuspotvictor
authored and
victor
committed
BUG pandas-dev#19860 Corrected use of mixed indexes with .at (pandas-dev#22436)
1 parent 73e9449 commit 5d1af2f

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ Indexing
663663
- Fixed ``DataFrame[np.nan]`` when columns are non-unique (:issue:`21428`)
664664
- Bug when indexing :class:`DatetimeIndex` with nanosecond resolution dates and timezones (:issue:`11679`)
665665
- Bug where indexing with a Numpy array containing negative values would mutate the indexer (:issue:`21867`)
666+
- Bug where mixed indexes wouldn't allow integers for ``.at`` (:issue:`19860`)
666667
- ``Float64Index.get_loc`` now raises ``KeyError`` when boolean key passed. (:issue:`19087`)
667668

668669
Missing

pandas/core/indexes/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3125,8 +3125,8 @@ def get_value(self, series, key):
31253125
iloc = self.get_loc(key)
31263126
return s[iloc]
31273127
except KeyError:
3128-
if (len(self) > 0 and
3129-
self.inferred_type in ['integer', 'boolean']):
3128+
if (len(self) > 0
3129+
and (self.holds_integer() or self.is_boolean())):
31303130
raise
31313131
elif is_integer(key):
31323132
return s[key]
@@ -3139,7 +3139,7 @@ def get_value(self, series, key):
31393139
return self._engine.get_value(s, k,
31403140
tz=getattr(series.dtype, 'tz', None))
31413141
except KeyError as e1:
3142-
if len(self) > 0 and self.inferred_type in ['integer', 'boolean']:
3142+
if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
31433143
raise
31443144

31453145
try:

pandas/core/indexing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2354,7 +2354,7 @@ def _convert_key(self, key, is_setter=False):
23542354
raise ValueError("At based indexing on an integer index "
23552355
"can only have integer indexers")
23562356
else:
2357-
if is_integer(i):
2357+
if is_integer(i) and not ax.holds_integer():
23582358
raise ValueError("At based indexing on an non-integer "
23592359
"index can only have non-integer "
23602360
"indexers")

pandas/tests/indexing/test_indexing.py

+32
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,22 @@ def test_index_contains(self, index, val):
610610
def test_index_not_contains(self, index, val):
611611
assert val not in index
612612

613+
@pytest.mark.parametrize("index,val", [
614+
(Index([0, 1, '2']), 0),
615+
(Index([0, 1, '2']), '2'),
616+
])
617+
def test_mixed_index_contains(self, index, val):
618+
# GH 19860
619+
assert val in index
620+
621+
@pytest.mark.parametrize("index,val", [
622+
(Index([0, 1, '2']), '1'),
623+
(Index([0, 1, '2']), 2),
624+
])
625+
def test_mixed_index_not_contains(self, index, val):
626+
# GH 19860
627+
assert val not in index
628+
613629
def test_index_type_coercion(self):
614630

615631
with catch_warnings(record=True):
@@ -710,6 +726,22 @@ def test_float_index_at_iat(self):
710726
for i in range(len(s)):
711727
assert s.iat[i] == i + 1
712728

729+
def test_mixed_index_assignment(self):
730+
# GH 19860
731+
s = Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 1, 2])
732+
s.at['a'] = 11
733+
assert s.iat[0] == 11
734+
s.at[1] = 22
735+
assert s.iat[3] == 22
736+
737+
def test_mixed_index_no_fallback(self):
738+
# GH 19860
739+
s = Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 1, 2])
740+
with pytest.raises(KeyError):
741+
s.at[0]
742+
with pytest.raises(KeyError):
743+
s.at[4]
744+
713745
def test_rhs_alignment(self):
714746
# GH8258, tests that both rows & columns are aligned to what is
715747
# assigned to. covers both uniform data-type & multi-type cases

pandas/tests/indexing/test_scalar.py

+30
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,33 @@ def test_at_with_tz(self):
170170

171171
result = df.at[0, 'date']
172172
assert result == expected
173+
174+
def test_mixed_index_at_iat_loc_iloc_series(self):
175+
# GH 19860
176+
s = Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 1, 2])
177+
for el, item in s.iteritems():
178+
assert s.at[el] == s.loc[el] == item
179+
for i in range(len(s)):
180+
assert s.iat[i] == s.iloc[i] == i + 1
181+
182+
with pytest.raises(KeyError):
183+
s.at[4]
184+
with pytest.raises(KeyError):
185+
s.loc[4]
186+
187+
def test_mixed_index_at_iat_loc_iloc_dataframe(self):
188+
# GH 19860
189+
df = DataFrame([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]],
190+
columns=['a', 'b', 'c', 1, 2])
191+
for rowIdx, row in df.iterrows():
192+
for el, item in row.iteritems():
193+
assert df.at[rowIdx, el] == df.loc[rowIdx, el] == item
194+
195+
for row in range(2):
196+
for i in range(5):
197+
assert df.iat[row, i] == df.iloc[row, i] == row * 5 + i
198+
199+
with pytest.raises(KeyError):
200+
df.at[0, 3]
201+
with pytest.raises(KeyError):
202+
df.loc[0, 3]

0 commit comments

Comments
 (0)