How indexing works in Pandas?

When you are attempting to slice with myseries[something], the something is often ambiguous. You are highlighting a case of that ambiguity. In your case, pandas is trying to help you out by guessing what you mean.

myseries_one[0] #As expected
Out[74]: 0.29129291112626043

myseries_one has integer labels. It would make sense that when you attempt to slice with an integer that you intend to get the element that is labeled with that integer. It turns out, that you have an element labeled with 0 an so that is returned to you.

myseries_two[0] #As expected
Out[75]: 0.29129291112626043

myseries_two has string labels. It’s highly unlikely that you meant to slice this series with a label of 0 when labels are all strings. So, pandas assumes that you meant a position of 0 and returns the first element (thanks pandas, that was helpful).

myseries_three[0]
KeyError:0 

myseries_three has integer labels and you are attempting to slice with an integer… perfect. Let’s just get that value for you… KeyError. Whoops, that index label does not exist. In this case, it is safer for pandas to fail than to guess that maybe you meant to slice by position. The documentation even suggests that if you want to remove the ambiguity, use loc for label based slicing and iloc for position based slicing.

Let’s try loc

myseries_one.loc[0]
0.29129291112626043

myseries_two.loc[0]
KeyError:0 

myseries_three.loc[0]
KeyError:0 

Only myseries_one has a label 0. The other two return KeyErrors

Let’s try iloc

myseries_one.iloc[0]
0.29129291112626043

myseries_two.iloc[0]
0.29129291112626043

myseries_three.iloc[0]
0.29129291112626043

They all have a position of 0 and return the first element accordingly.


For the range slicing, pandas decides to be less interpretive and sticks to positional slicing for the integer slice 0:2. Keep in mind. Actual real people (the programmers writing pandas code) are the ones making these decisions. When you are attempting to do something that is ambiguous, you may get varying results. To remove ambiguity, use loc and iloc.

iloc

myseries_one.iloc[0:2]

0    0.291293
1    0.381014
dtype: float64

myseries_two.iloc[0:2]

a    0.291293
b    0.381014
dtype: float64

myseries_three.iloc[0:2]

10    0.291293
11    0.381014
dtype: float64

loc

myseries_one.loc[0:2]

0    0.291293
1    0.381014
2    0.923360
dtype: float64

myseries_two.loc[0:2]

TypeError: cannot do slice indexing on <class 'pandas.indexes.base.Index'> with these indexers [0] of <type 'int'>

myseries_three.loc[0:2]

Series([], dtype: float64)

Leave a Comment