HOWTO · Pandas

在 Pandas Dataframe 中设置列作为索引

本教程演示如何使用 DataFrame 的 `set_index()` 方法将某一列设为索引,以及如何在读取文件时使用 `index_col` 参数。

本页内容

新的 Pandas DataFrame 默认使用整数索引来标识行。若要使用有意义的行标签,可以对现有 DataFrame 调用 set_index(),也可以在加载文件时将 index_col 传给 read_csv 或 read_excel。前一种方式适用于数据已在内存中的情况;后一种方式则在导入文件时选择行标签。下面的示例使用同一份小型人员数据集,便于比较结果。选择一列值能让分析中的各行易于识别的列;索引可以包含重复值,但按重复标签查找时可能会返回多行。

使用 set_index() 将 DataFrame 的一列设为索引

set_index() 是 DataFrame 的方法。默认情况下,它会返回一个新的 DataFrame,并从普通列中移除被选中的列。如果要保持原 DataFrame 不变,请将返回结果赋给变量。传入列名列表可以创建 MultiIndex,使每行由一组值共同标识。如果还想让选中的值保留为普通数据列,请使用 drop=False。

这些选项会影响数据的访问方式,而不会丢弃行。例如,如果后续代码既要将姓名用作标签,也要将其作为值使用,就保留姓名列;如果城市和年龄的组合对你的工作有意义,则可以使用这两列创建 MultiIndex。如果要直接修改现有 DataFrame,set_index(..., inplace=True) 会执行原地修改并返回 None;通常,将默认返回的新 DataFrame 赋给变量更易理解,也能保留原数据。要恢复普通索引,reset_index() 会将当前索引值放回列中,并默认给结果分配新的整数索引。在导出数据或后续操作要求标签为普通列时,这样做很有用。

下面的示例创建人员 DataFrame,然后分别使用一列和两列创建索引,也展示了如何在将姓名用作行标签时保留姓名列。示例中的列名和显示标签保持英文,以便与不可更改的代码及输出一致。

import pandas as pd

people = pd.DataFrame({
    "Name": ["Alice", "Bob", "Charlie"],
    "City": ["New York", "Los Angeles", "Chicago"],
    "Age": [25, 30, 35],
})

by_name = people.set_index("Name")
by_city_and_age = people.set_index(["City", "Age"])
with_name_column = people.set_index("Name", drop=False)

print(by_name)

这里,by_name 使用姓名作为行标签,并将 City 和 Age 保留为数据列。by_city_and_age 使用选中的两列创建 MultiIndex,而 with_name_column 使用姓名作为标签,同时保留 Name 列。赋值操作会创建独立的 DataFrame,因此 people 仍保留原有列和默认索引。打印语句显示单列索引的结果;另外两个变量也可以用同样的方式查看。示例中显示的列名 Name、City 和 Age 保持英文。若要恢复普通整数索引并将索引值放回列中,可以调用 by_name.reset_index();该方法会返回另一个 DataFrame。如果要继续使用重置索引后的版本,可以将结果赋给变量。

在读取 CSV 或 Excel 文件时使用 index_col 设置索引

如果数据来自文件,可以在读取数据时选择索引。这个完整的 CSV 示例使用与上方 DataFrame 相同的列名和记录。StringIO 使 read_csv 可以直接读取示例文本;如果磁盘上已有 CSV 文件,可以将其替换为文件路径,例如 "people.csv"。示例中的列名保持英文,与不可更改的代码及输出一致:

from io import StringIO
import pandas as pd

csv_data = StringIO("""Name,City,Age
Alice,New York,25
Bob,Los Angeles,30
Charlie,Chicago,35
""")
people = pd.read_csv(csv_data, index_col="Name")

print(people)

参数 index_col="Name" 按列标题选择列,因此生成的索引和剩余数据列与第一个示例中的 by_name 一致。数值型 index_col 则按从零开始的位置选择列,第一列的位置为 0;使用列标题可以明确指定目标,也较少受列顺序变化的影响。如果要选择多列,可以传入列表,例如 index_col=["City", "Age"],在导入时创建 MultiIndex。对于 Excel 工作簿,可以使用对应的读取调用 pd.read_excel("people.xlsx", index_col="Name")。工作簿必须可用,并且 pandas 需要安装能够读取该文件格式的 Excel 引擎。这里仅展示 Excel 调用的写法,因为没有提供工作簿。若列标题拼写有误或文件中的列顺序发生变化,请先确认文件的列名,再选择索引,以确保选中预期字段。