LOC vs ILOC - DataFrame Indexing and Labeling

Use LOC to select data by labels and ILOC to select data by integer positions in Pandas DataFrames.

Master the nuances of pandas indexing by learning the vital differences between LOC (label-based) and ILOC (integer-based). Streamline your data manipulation tasks by referencing DataFrame elements intuitively by name or index.

Key Insights

  • Differentiate clearly between pandas' LOC and ILOC indexing methods; LOC selects data using label names, while ILOC relies on integer positions for rows and columns.
  • Understand indexing inclusivity: LOC is inclusive of endpoint labels (e.g., rows 0 to 2 include rows 0, 1, and 2), while ILOC indexing excludes the endpoint integer (e.g., rows 0 to 2 include only 0 and 1).
  • Use lists to select non-contiguous data effectively; for example, accessing specific chessboard positions or columns such as "item" and "calories" in a DataFrame from Noble Desktop's examples.

Note: These materials offer prospective students a preview of how our classes are structured. Students enrolled in this course will receive access to the full set of materials, including video lectures, project-based assignments, and instructor feedback.

This is a lesson preview only. For the full lesson, purchase the course here.

But the columns are typically not left as 0,1, 2,3. They're given named labels. If you'd like to refer, look up data, take slices, or get individual values using the names of the columns, then it's LOC, not ILOC. LOC means location, not ILOC, which is integer location.

So it's named location. If the row names are the same as the row index, you can use index numbers for rows. So a lot of times, the rows are the same.

Row 0 has an index, an ILOC 0, and a LOC 0. But the names of the columns are typically not the same as the index in NumPy, right? Like our fooddf does not have 0,1, 2,3 for columns. It's got item, price, cals, and vegan. If we wanted to look up the prices or something, we don't want to have to know that "price" under the hood is really column 1, while "item" is column 0, and so on.

Let's back up to the chessboard for just a minute. And we're going to set the rooks to be RK instead of R. Let's go back and look at our chessboard for a moment. So let's say we want to come in and use RK for the rooks.

Not that we need to, but we just want to be able to practice referencing or isolating cells by the name of the columns and the names of the rows. The rows are different also, right? Row 0 by ILOC, the index is labeled 8 using LOC. Column 0 in ILOC, which is what we've been using, right? Row 0, row 7, column 4, row 0, row 7, column 2 and 5. We're using the indexes. We're ignoring these letters and this 8 to 1 backwards counting.

Python for Data Science Bootcamp: Live & Hands-on, In NYC or Online, Learn From Experts, Free Retake, Small Class Sizes,  1-on-1 Bonus Training. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.

We're just going 0 to 7 for the columns and 0 to 7 for the rows. But we could have done all those commands by referencing the label names of the columns and rows. So going back to the chessboard for a moment, let's target the rooks.

And what we want to do is change the existing R to RK, just so we can see if we made a change. But this time, we want to use LOC, not ILOC. So that means we're going to refer to the rows and columns by their name.

That is A to H for the columns and 8 to 1 backwards for the rows—not by the index number, which in both cases of columns and rows goes 0 to 7. And this way should be easier, more user-friendly, because you get to refer to columns by their names. So let's say chessboarddf. LOC this time.

And we want to go row 8 and row 1. Those are the top and bottom rows. And then we want to do columns A and column H. We want to set that equal to "rook". Last time, we had two lines.

We hit them one row at a time. I think we can just hit both rows at once, though. Let's see if it works.

There it is—RK, RK, all the way around. OK, little challenge: change the B, the bishop, to BP, say, for bishop.

Just seeing if you can target them using LOC, not ILOC. So pause, follow this format, and see if you can do it. And we'll check your solution when you come back. All right, here we go.

So it's the same rows 8 and 1, the top row and the bottom row. But it's not columns A and H anymore. Those are the extreme outside columns for the rooks.

We're coming in to C and F. And we're going to go bishop. Yep, it worked. All right, one more challenge.

Change P, pawn, to PN, PN, using LOC, not ILOC. Pause and come back for the solution when you're ready. OK, so to do that, we're going to say chessboard. LOC. And we want to target—OK, so remember, it's going to be row or rows.

We don't have ranges. We have non-continuous items. We want row 7 and row 2. Because we're using the labels. Comma, they're discontinuous.

They don't touch. We feed them in as a list. And then for the columns, we want all.

We put a colon. And I think that ought to do it. Oh, we didn't set it to anything.

OK, so to set it to something, we'll say "PN". There you go. It worked.

There's your pawns. So targeting with LOC versus ILOC. Now let's get all three of them in view at once, so you can camp out and type that out like so.

Your rooks—we're just using LOC instead of ILOC to target by label name, the letters, not the index underlying it. Remember, A to H under the hood is 0 to 7. 8 to 1 under the hood is 0 to 7. And we just want to make a superficial change, add a letter to each one of these so we know it worked. Now back to the fooddf using LOC.

Let's get the first three rows—ILOC rather. Let's go back to ILOC, because we want to contrast that with LOC. We'll do both.

We're going to use the ILOC to get the first three rows, first three columns. We don't want the vegan column, and we don't want the last row, which is the salad row. If we get the first three rows, there's no salad. And if we get the first three columns, there's no vegan.

We're going to say—and we don't need to make a new df. Let's just print it directly. We'll say fooddf.iloc, square bracket.

Now we need the numbers. We're going to say from 0 to 3 for rows (0,1, and 2), and for columns, likewise, from 0 to 3. And there you go. No vegan column, no garden salad.

Now let's take that exact same thing, except using LOC, not ILOC. Using LOC, let's get the first three rows. Now ILOC—here's a weird thing.

ILOC is exclusive, right? So to get 0,1, 2, we have to go all the way to 3. But LOC is inclusive. So you just go to row 2 then. In other words, if you go to row 3 with LOC, it will give you everything up to and including row 3.

So let's say LOC—we'll try that. The first three rows—they have the same number.

Their names for LOC are the same as their numbers for ILOC because they don't have any special labels. But you can't say :3 for columns with LOC. It'll break, because LOC is expecting the names of the columns.

So the names of the columns are going to be "item":"calories", like so. There you go. We're doing a range here, right? But instead of from 0 to 3, you're saying item to calories.

And notice you don't have to go past calories. Calories is inclusive. LOC and ILOC are tricky.

It's going to take a while. Don't get frustrated with it. Just hang with it.

You're going to have to put your time in to get comfortable and good with ILOC versus LOC. Just remember, I is for numbers (integer), and LOC is for names. Challenge: using ILOC, get the first two rows, first two columns from the fooddf.

And then we have another challenge, the LOC version of the same. And then we're going to do these together. So just these next two cells—challenge, turn off the recorder, turn off the video, and pause it, and turn it back on when you're ready.

All right, here we go. We're going to say, fooddf.iloc, right? We want the first two rows. We're going to say :2 to get rows 0 and 1. And columns—same deal, because we want the first two.

And indeed, we got the first two, right? Item and price are the first two columns. And 0 and 1 are the first two rows. Now, the exact same thing, except we want the first two rows and columns.

So you don't change the rows, because the names of the rows and the index of the rows are the same, since we never changed their names. But we did change the default 0,1, 2,3 column names—you know, we set those when we declared the columns. But under the hood, it's 0,1, 2,3, which is why we were able with ILOC to look up columns by number.

But now with LOC, we can't use numbers. We have to use the names. But you still do a range with a colon.

We're going to start at "item" and go to "price" like that. And we have to take out the I. That's fine. OK, there it is.

That's the difference—ILOC and LOC. ILOC uses numbers, LOC uses names. But this LOC is using numbers.

Well, that's because the numbers and the names are the same. ILOC is numbers. LOC is names.

Name of what? Name of columns that you're selecting. Numbers of what? The index number that's under the hood for all the columns and all the rows, starting at 0 and going up. OK, using LOC, get the first two rows, but get non-contiguous columns.

We want to skip "price" and go right to "cals". So to get non-contiguous columns, you don't use a colon because that's a span. You use a comma.

And you have to wrap the items in a little list. We're going to say mostly the same—fooddf. LOC—we want using LOC.

And we're going to say "item", "cals". And that's going to break because when you're doing non-contiguous (non-range) selections, you have to wrap them in a list. There you go.

So it's a 2 × 2, just like we did before, but it's not a range. It's a skip—non-contiguous. So the non-contiguous selection is a list of items, which we did with the chess set when selecting the bishop columns.

Those are non-contiguous, non-touching columns. Same with the knights. Same with the rooks.

All right, using LOC—non-contiguous—well, that would be LOC. Let's start with ILOC. First, we'll do ILOC.

Now, how do we do the ILOC version of this? The ILOC version would be—we want 0 and 2, which you also have to pass in as a list because they're not contiguous. And now that's ILOC for integer. And it still works.

So it's a subset. Ah, interesting. So notice we have three rows here.

Why? Because LOC is not exclusive. It's inclusive. When you say 0 to 2, you're getting 0,1, and 2. ILOC is exclusive.

When you say 0 to 2, you get 0 and 1. We have to make this a 1. There you go. Same. Get the first two rows.

Now first and last rows—"item" and "cals" columns. We have the non-contiguous columns, but what about the non-contiguous rows? We'll do first with ILOC and then LOC.

Now we're getting two rows again, but we're skipping. We're getting non-contiguous rows—the first and last. So what we're going to do is just type it—fooddf.iloc—and you have to feed in the row selections as a list.

We want row 0 and row 3—first and last. And for the columns, we want 0 and 2. There it is. And same deal with LOC.

We'll say fooddf.loc, and we want 0 and 3 again. And then for the columns, we want "item" and "cals", which have to be in a list since they're not contiguous or in a range. Here we go.

Same deal—LOC versus ILOC.

Brian McClain

Brian is an experienced instructor, curriculum developer, and professional web developer, who in recent years has served as Director for a coding bootcamp in New York. Brian joined Noble Desktop in 2022 and is a lead instructor for HTML & CSS, JavaScript, and Python for Data Science. He also developed Noble's cutting-edge Python for AI course. Prior to that, he taught Python Data Science and Machine Learning as an Adjunct Professor of Computer Science at Westchester County College.

More articles by Brian McClain

How to Learn Python

Master Python with hands-on training. Python is a popular object-oriented programming language used for data science, machine learning, and web development. 

Yelp Facebook LinkedIn YouTube Twitter Instagram