Selection has three common tools:
[]— columns (and boolean row masks).loc— labels.iloc— integer positions
Goal
Pick one column, several columns, a cell, and a slice without triggering SettingWithCopy confusion. Each block is a complete script.
Columns with []
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
print(df["name"])
print()
print(df[["name", "score"]])
print()
print("one column as a frame:")
print(df[["name"]])One pair of brackets returns a Series. Two brackets (a list) return a DataFrame, even for one column.
Rows and columns with loc
loc[row_labels, column_labels] — labels, inclusive slices.
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
print(df.loc[0])
print()
print(df.loc[0:2, ["name", "score"]])
print()
print(df.loc[df["team"] == "A", ["name", "score"]])Positions with iloc
iloc is like NumPy: start inclusive, end exclusive.
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
print(df.iloc[0])
print()
print(df.iloc[0:2, 0:2])
print()
print(df.iloc[[0, 3], [0, 1]])One cell: at / iat
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
print(df.at[1, "score"])
print(df.iat[1, 1])Copy before you edit a slice
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
team_a = df.loc[df["team"] == "A"].copy()
team_a["bonus"] = 5
print(team_a)
print()
print("original unchanged:")
print(df)Pitfall
df[df["team"] == "A"]["score"] = 100 may not write back to df. Select with loc in one step: df.loc[df["team"] == "A", "score"] = 100.
df = pd.DataFrame(
{
"name": ["Ada", "Alan", "Grace", "Linus"],
"score": [98, 91, 95, 88],
"team": ["A", "B", "A", "B"],
}
)
df.loc[df["team"] == "A", "score"] = 100
print(df)