10. 索引设置与重置 1. 概述 索引是 Pandas 数据的"行标签",合理设置索引可以提升数据访问效率、简化操作。本章学习如何设置、重置和操作 DataFrame 的行索引。
import pandasas pdimport numpyas np# 创建示例数据 df= pd. DataFrame( { 'ID' : [ 1001 , 1002 , 1003 , 1004 , 1005 ] , '姓名' : [ '张三' , '李四' , '王五' , '赵六' , '钱七' ] , '年龄' : [ 25 , 30 , 28 , 32 , 35 ] , '城市' : [ '北京' , '上海' , '广州' , '深圳' , '杭州' ] , '工资' : [ 8000 , 12000 , 10000 , 15000 , 11000 ] } ) print ( "原始数据:" ) print ( df) print ( f"\n当前索引: { df. index. tolist( ) } " ) 2. 查看索引 # 查看索引 print ( f"索引对象: { df. index} " ) print ( f"索引类型: { type ( df. index) } " ) print ( f"索引值列表: { df. index. tolist( ) } " ) # 查看索引名称(默认 None) print ( f"索引名称: { df. index. name} " ) 3. 设置索引 3.1 set_index() - 将列设置为索引 # 将单列设置为索引 df_id= df. set_index( 'ID' ) print ( "设置 ID 为索引:" ) print ( df_id) print ( f"新索引: { df_id. index. tolist( ) } " ) # 原 DataFrame 不变(默认返回新 DataFrame) print ( "\n原 DataFrame 不变:" ) print ( df. index. tolist( ) ) # 原地修改 df. set_index( 'ID' , inplace= True ) print ( "\n原地修改后:" ) print ( df) 3.2 多列作为索引(MultiIndex) # 恢复原始数据 df= pd. DataFrame( { 'ID' : [ 1001 , 1002 , 1003 , 1004 , 1005 ] , '姓名' : [ '张三' , '李四' , '王五' , '赵六' , '钱七' ] , '年龄' : [ 25 , 30 , 28 , 32 , 35 ] , '城市' : [ '北京' , '上海' , '广州' , '深圳' , '杭州' ] , '工资' : [ 8000 , 12000 , 10000 , 15000 , 11000 ] } ) # 设置多列索引 df_multi= df. set_index( [ '城市' , 'ID' ] ) print ( "设置城市和ID为索引:" ) print ( df_multi) print ( f"\n索引层级: { df_multi. index. names} " ) 3.3 设置索引时保留原列 # drop=False 保留原列 df_with_keep= df. set_index( 'ID' , drop= False ) print ( "保留原列:" ) print ( df_with_keep) 3.4 设置索引时排序 # append=True 追加到现有索引 df_indexed= df. set_index( 'ID' ) df_appended= df_indexed. set_index( '城市' , append= True ) print ( "追加索引:" ) print ( df_appended) 4. 重置索引 4.1 reset_index() - 将索引变为列 # 重置索引(索引变成普通列) df_reset= df. set_index( 'ID' ) . reset_index( ) print ( "重置索引:" ) print ( df_reset) # drop=True 丢弃索引(不保留为列) df_drop= df. set_index( 'ID' ) . reset_index( drop= True ) print ( "\n重置索引并丢弃:" ) print ( df_drop) 4.2 重置部分索引层级 # 创建多层索引 df_multi= df. set_index( [ '城市' , 'ID' ] ) print ( "多层索引:" ) print ( df_multi) # 只重置第一层索引 df_reset_level= df_multi. reset_index( level= 0 ) print ( "\n只重置城市层级:" ) print ( df_reset_level) # 重置所有层级 df_reset_all= df_multi. reset_index( ) print ( "\n重置所有层级:" ) print ( df_reset_all) 5. 重命名索引 5.1 重命名索引名称 df_indexed= df. set_index( 'ID' ) # 方法1:直接赋值 df_indexed. index. name= '员工ID' print ( "重命名索引:" ) print ( df_indexed) # 方法2:使用 rename_axis df_indexed= df_indexed. rename_axis( '编号' ) print ( "\n使用 rename_axis:" ) print ( df_indexed) 5.2 重命名索引值 # 使用 rename 重命名索引值 df_indexed= df. set_index( '姓名' ) print ( "原始:" ) print ( df_indexed) df_renamed= df_indexed. rename( index= { '张三' : '张先生' , '李四' : '李先生' } ) print ( "\n重命名索引值:" ) print ( df_renamed) 6. 索引排序 6.1 sort_index() - 按索引排序 # 创建乱序数据 np. random. seed( 42 ) df_shuffled= df. sample( frac= 1 ) print ( "乱序数据:" ) print ( df_shuffled) # 按索引排序 df_sorted= df_shuffled. sort_index( ) print ( "\n按索引排序:" ) print ( df_sorted) # 降序排列 df_desc= df_shuffled. sort_index( ascending= False ) print ( "\n降序排列:" ) print ( df_desc) 7. 索引操作 7.1 修改索引值 df_indexed= df. set_index( 'ID' ) print ( "原始:" ) print ( df_indexed) # 修改索引值 df_indexed. index= [ 2001 , 2002 , 2003 , 2004 , 2005 ] print ( "\n修改索引值:" ) print ( df_indexed) 7.2 索引去重 # 创建重复索引的数据 df_dup= pd. DataFrame( { '值' : [ 10 , 20 , 30 , 40 , 50 ] } , index= [ 'A' , 'B' , 'A' , 'C' , 'B' ] ) print ( "重复索引数据:" ) print ( df_dup) # 检查索引是否重复 print ( f"索引是否重复: { df_dup. index. is_unique} " ) # 去重(保留第一个) df_unique= df_dup[ ~ df_dup. index. duplicated( keep= 'first' ) ] print ( "\n去重后:" ) print ( df_unique) 7.3 索引类型转换 df_indexed= df. set_index( 'ID' ) print ( f"索引类型: { type ( df_indexed. index) } " ) # 转换为列表 index_list= df_indexed. index. tolist( ) print ( f"索引列表: { index_list} " ) # 转换为数组 index_array= df_indexed. index. valuesprint ( f"索引数组: { index_array} " ) 8. 实战示例:用户数据索引优化 # 创建用户数据 np. random. seed( 42 ) users= pd. DataFrame( { 'user_id' : [ f'U { i: 04d } ' for iin range ( 1 , 21 ) ] , '姓名' : [ f'用户_ { i} ' for iin range ( 1 , 21 ) ] , '年龄' : np. random. randint( 18 , 60 , 20 ) , '城市' : np. random. choice( [ '北京' , '上海' , '广州' , '深圳' , '杭州' ] , 20 ) , '注册时间' : pd. date_range( '2024-01-01' , periods= 20 , freq= 'D' ) , '消费金额' : np. random. randint( 100 , 10000 , 20 ) } ) print ( "=" * 60 ) print ( "用户数据索引优化" ) print ( "=" * 60 ) print ( "\n1. 原始数据:" ) print ( users. head( ) ) print ( f"索引: { users. index. tolist( ) } " ) # 2. 设置 user_id 为索引 print ( "\n2. 设置 user_id 为索引:" ) users_indexed= users. set_index( 'user_id' ) print ( users_indexed. head( ) ) # 3. 按索引查询(快速) print ( "\n3. 按索引查询用户 U0005:" ) print ( users_indexed. loc[ 'U0005' ] ) # 4. 按索引排序 print ( "\n4. 按用户ID降序:" ) print ( users_indexed. sort_index( ascending= False ) . head( ) ) # 5. 重置索引 print ( "\n5. 重置索引:" ) users_reset= users_indexed. reset_index( ) print ( users_reset. head( ) ) # 6. 多级索引:按城市和用户ID print ( "\n6. 多级索引(城市 + user_id):" ) users_multi= users. set_index( [ '城市' , 'user_id' ] ) print ( users_multi. head( ) ) # 7. 按第一级索引筛选 print ( "\n7. 筛选北京用户:" ) print ( users_multi. loc[ '北京' ] . head( ) ) 9. 索引最佳实践 9.1 何时设置索引 场景 建议 有唯一标识列 设置为索引,方便查询 需要按某列快速查找 设置为索引 需要分组聚合 可以设置为索引 时间序列数据 设置为 DatetimeIndex 数据需要合并 设置为合并键
9.2 索引类型选择 # 默认索引:RangeIndex(整数索引) # 优点:简单、内存小 # 缺点:语义不明确 # 自定义索引: # - 唯一标识:如 ID、用户名 # - 时间:日期时间索引 # - 分类:类别索引 # 时间索引示例 df_time= pd. DataFrame( { '值' : range ( 10 ) } , index= pd. date_range( '2024-01-01' , periods= 10 , freq= 'D' ) ) print ( "时间索引:" ) print ( df_time) print ( f"索引类型: { type ( df_time. index) } " ) 9.3 索引性能 # 索引查询比普通列查询快 import time# 创建大数据集 large_df= pd. DataFrame( { 'id' : range ( 100000 ) , 'value' : np. random. randn( 100000 ) } ) # 普通列查询 start= time. time( ) result1= large_df[ large_df[ 'id' ] == 50000 ] print ( f"列查询耗时: { time. time( ) - start: .5f } 秒" ) # 索引查询 large_df_indexed= large_df. set_index( 'id' ) start= time. time( ) result2= large_df_indexed. loc[ 50000 ] print ( f"索引查询耗时: { time. time( ) - start: .5f } 秒" ) 10. 总结 操作 方法 说明 设置索引 df.set_index('列名')将列设置为索引 设置索引(保留列) df.set_index('列名', drop=False)保留原列 多列索引 df.set_index(['列1', '列2'])创建多层索引 重置索引 df.reset_index()索引变为列 重置并丢弃 df.reset_index(drop=True)丢弃索引 重命名索引名 df.rename_axis('新名称')修改索引名称 重命名索引值 df.rename(index={'旧':'新'})修改索引值 索引排序 df.sort_index()按索引排序 索引去重 df.index.is_unique检查重复