df.loc versus df.iloc

import pandas as pd
df = pd.read_csv('rates.csv', parse_dates=['Time'])
df.index = df['Time']
df.head()
Time USD JPY BGN CZK DKK GBP CHF
Time
2024-01-17 2024-01-17 1.0877 160.65 1.9558 24.755 7.4586 0.85818 0.9406
2024-01-16 2024-01-16 1.0882 159.64 1.9558 24.710 7.4582 0.86078 0.9361
2024-01-15 2024-01-15 1.0945 159.67 1.9558 24.714 7.4590 0.86075 0.9351
2024-01-12 2024-01-12 1.0942 159.17 1.9558 24.689 7.4565 0.85950 0.9350
2024-01-11 2024-01-11 1.0987 159.71 1.9558 24.659 7.4568 0.86145 0.9338

loc lets us access rows/columns using labels

df.loc[:, ['USD', 'GBP']]
USD GBP
Time
2024-01-17 1.0877 0.85818
2024-01-16 1.0882 0.86078
2024-01-15 1.0945 0.86075
2024-01-12 1.0942 0.85950
2024-01-11 1.0987 0.86145
... ... ...
2023-10-26 1.0540 0.87170
2023-10-25 1.0576 0.87240
2023-10-24 1.0632 0.87025
2023-10-23 1.0597 0.87153
2023-10-20 1.0591 0.87213

61 rows × 2 columns

df.loc[["2024-01-17", "2023-10-20"], ['USD', 'GBP']]
USD GBP
Time
2024-01-17 1.0877 0.85818
2023-10-20 1.0591 0.87213
df.loc["2023-11", ['USD', 'GBP']]
USD GBP
Time
2023-11-30 1.0931 0.86368
2023-11-29 1.0985 0.86525
2023-11-28 1.0949 0.86820
2023-11-27 1.0951 0.86671
2023-11-24 1.0916 0.86818
2023-11-23 1.0900 0.86940
2023-11-22 1.0911 0.87030
2023-11-21 1.0955 0.87326
2023-11-20 1.0928 0.87630
2023-11-17 1.0872 0.87395
2023-11-16 1.0849 0.87520
2023-11-15 1.0868 0.87188
2023-11-14 1.0724 0.87230
2023-11-13 1.0670 0.87155
2023-11-10 1.0683 0.87435
2023-11-09 1.0691 0.87205
2023-11-08 1.0671 0.87015
2023-11-07 1.0686 0.86855
2023-11-06 1.0741 0.86640
2023-11-03 1.0702 0.86983
2023-11-02 1.0661 0.87305
2023-11-01 1.0537 0.86945
df.loc[:, ['USD', 'GBP']] # same as df[['USD', 'GBP']]
USD GBP
Time
2024-01-17 1.0877 0.85818
2024-01-16 1.0882 0.86078
2024-01-15 1.0945 0.86075
2024-01-12 1.0942 0.85950
2024-01-11 1.0987 0.86145
... ... ...
2023-10-26 1.0540 0.87170
2023-10-25 1.0576 0.87240
2023-10-24 1.0632 0.87025
2023-10-23 1.0597 0.87153
2023-10-20 1.0591 0.87213

61 rows × 2 columns

df[['USD', 'GBP']]
USD GBP
Time
2024-01-17 1.0877 0.85818
2024-01-16 1.0882 0.86078
2024-01-15 1.0945 0.86075
2024-01-12 1.0942 0.85950
2024-01-11 1.0987 0.86145
... ... ...
2023-10-26 1.0540 0.87170
2023-10-25 1.0576 0.87240
2023-10-24 1.0632 0.87025
2023-10-23 1.0597 0.87153
2023-10-20 1.0591 0.87213

61 rows × 2 columns

iloc lets us access rows/columns by integer index (starting at 0)

df.head()
Time USD JPY BGN CZK DKK GBP CHF
Time
2024-01-17 2024-01-17 1.0877 160.65 1.9558 24.755 7.4586 0.85818 0.9406
2024-01-16 2024-01-16 1.0882 159.64 1.9558 24.710 7.4582 0.86078 0.9361
2024-01-15 2024-01-15 1.0945 159.67 1.9558 24.714 7.4590 0.86075 0.9351
2024-01-12 2024-01-12 1.0942 159.17 1.9558 24.689 7.4565 0.85950 0.9350
2024-01-11 2024-01-11 1.0987 159.71 1.9558 24.659 7.4568 0.86145 0.9338
df.loc[:, 1:3] # loc expects labels for rows and columns
TypeError: cannot do slice indexing on Index with these indexers [1] of type int
df.iloc[:, 1:3]
USD JPY
Time
2024-01-17 1.0877 160.65
2024-01-16 1.0882 159.64
2024-01-15 1.0945 159.67
2024-01-12 1.0942 159.17
2024-01-11 1.0987 159.71
... ... ...
2023-10-26 1.0540 158.48
2023-10-25 1.0576 158.55
2023-10-24 1.0632 159.26
2023-10-23 1.0597 158.91
2023-10-20 1.0591 158.80

61 rows × 2 columns

df.iloc[:, 1:].head() # all columns except 0th one
USD JPY BGN CZK DKK GBP CHF
Time
2024-01-17 1.0877 160.65 1.9558 24.755 7.4586 0.85818 0.9406
2024-01-16 1.0882 159.64 1.9558 24.710 7.4582 0.86078 0.9361
2024-01-15 1.0945 159.67 1.9558 24.714 7.4590 0.86075 0.9351
2024-01-12 1.0942 159.17 1.9558 24.689 7.4565 0.85950 0.9350
2024-01-11 1.0987 159.71 1.9558 24.659 7.4568 0.86145 0.9338
df.iloc[:10, 1:4].head() # select a few rows, only keep columns 1,2,3
USD JPY BGN
Time
2024-01-17 1.0877 160.65 1.9558
2024-01-16 1.0882 159.64 1.9558
2024-01-15 1.0945 159.67 1.9558
2024-01-12 1.0942 159.17 1.9558
2024-01-11 1.0987 159.71 1.9558