索引操作 #
索引概述 #
索引是 Pandas 的核心概念之一,它提供了数据访问的标签系统。理解索引对于高效使用 Pandas 至关重要。
text
┌─────────────────────────────────────────────────────────────┐
│ Pandas 索引 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 行索引(Index) │
│ ├── 标识每一行数据 │
│ ├── 可以是任意可哈希类型 │
│ └── 支持重复值 │
│ │
│ 列索引(Columns) │
│ ├── 标识每一列数据 │
│ ├── 通常是字符串 │
│ └── 唯一值 │
│ │
│ 多层索引(MultiIndex) │
│ ├── 层次化索引 │
│ ├── 支持多维数据 │
│ └── 高级数据选择 │
│ │
└─────────────────────────────────────────────────────────────┘
索引类型 #
RangeIndex #
python
import pandas as pd
# 默认索引
df = pd.DataFrame({'A': [1, 2, 3]})
print(df.index) # RangeIndex(start=0, stop=3, step=1)
# 创建 RangeIndex
idx = pd.RangeIndex(start=0, stop=10, step=2)
print(idx) # RangeIndex(start=0, stop=10, step=2)
Index(通用索引) #
python
# 列表创建
idx = pd.Index([1, 2, 3, 4, 5])
print(idx) # Index([1, 2, 3, 4, 5], dtype='int64')
# 字符串索引
idx = pd.Index(['a', 'b', 'c'])
print(idx) # Index(['a', 'b', 'c'], dtype='object')
# 日期索引
idx = pd.date_range('2024-01-01', periods=5)
print(idx) # DatetimeIndex(['2024-01-01', ...], dtype='datetime64[ns]', freq='D')
DatetimeIndex #
python
# 创建日期索引
idx = pd.DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03'])
# 使用 date_range
idx = pd.date_range('2024-01-01', periods=5, freq='D')
idx = pd.date_range('2024-01-01', '2024-12-31', freq='M') # 月末
# 日期属性
print(idx.year)
print(idx.month)
print(idx.day)
print(idx.dayofweek)
PeriodIndex #
python
# 创建周期索引
idx = pd.PeriodIndex(['2024-01', '2024-02', '2024-03'], freq='M')
# 使用 period_range
idx = pd.period_range('2024-01', periods=5, freq='M')
# 周期属性
print(idx.year)
print(idx.month)
TimedeltaIndex #
python
# 创建时间差索引
idx = pd.TimedeltaIndex(['1 day', '2 days', '3 days'])
# 使用 timedelta_range
idx = pd.timedelta_range(start='1 day', periods=5, freq='D')
CategoricalIndex #
python
# 创建分类索引
idx = pd.CategoricalIndex(['a', 'b', 'c', 'a', 'b'])
# 有序分类
idx = pd.CategoricalIndex(['low', 'medium', 'high'],
categories=['low', 'medium', 'high'],
ordered=True)
索引属性 #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 索引对象
print(df.index)
# 索引值
print(df.index.values)
# 索引名称
print(df.index.name)
# 索引数据类型
print(df.index.dtype)
# 索引是否唯一
print(df.index.is_unique)
# 索引是否有重复
print(df.index.has_duplicates)
# 索引长度
print(len(df.index))
# 索引形状
print(df.index.shape)
设置索引 #
创建时设置 #
python
# 创建时指定索引
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 从字典创建
df = pd.DataFrame({'A': [1, 2, 3]}, index=pd.Index(['a', 'b', 'c'], name='idx'))
set_index #
python
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'city': ['New York', 'London', 'Tokyo']
})
# 设置单列为索引
df = df.set_index('name')
# 设置多列为索引
df = df.set_index(['city', 'name'])
# 保留原列
df = df.set_index('name', drop=False)
# 追加索引
df = df.set_index('city', append=True)
reset_index #
python
# 重置索引
df = df.reset_index()
# 不保留原索引
df = df.reset_index(drop=True)
# 重置特定层
df = df.reset_index(level=0) # 多层索引时
索引操作 #
修改索引 #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 直接赋值
df.index = ['x', 'y', 'z']
# 修改索引名
df.index.name = 'new_index'
# rename_axis
df = df.rename_axis('rows')
df = df.rename_axis(index='rows', columns='cols')
重命名索引 #
python
# 重命名索引值
df = df.rename(index={'a': 'A', 'b': 'B'})
# 重命名列
df = df.rename(columns={'A': 'a', 'B': 'b'})
# 同时重命名
df = df.rename(index={'a': 'A'}, columns={'A': 'a'})
索引排序 #
python
# 排序索引
df = df.sort_index()
df = df.sort_index(ascending=False)
# 排序列
df = df.sort_index(axis=1)
# 按索引值排序
df = df.sort_values(by='column')
索引选择 #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 检查索引是否存在
print('a' in df.index) # True
# 获取索引位置
print(df.index.get_loc('b')) # 1
# 获取多个索引位置
print(df.index.get_indexer(['a', 'c'])) # [0, 2]
# 切片
print(df.index[0:2])
print(df.index[:'b']) # 标签切片(包含结束)
多层索引(MultiIndex) #
创建多层索引 #
python
import pandas as pd
# 从数组创建
arrays = [
['a', 'a', 'b', 'b'],
[1, 2, 1, 2]
]
index = pd.MultiIndex.from_arrays(arrays, names=['letter', 'number'])
df = pd.DataFrame({'A': [1, 2, 3, 4]}, index=index)
# 从元组创建
tuples = [('a', 1), ('a', 2), ('b', 1), ('b', 2)]
index = pd.MultiIndex.from_tuples(tuples, names=['letter', 'number'])
# 从产品创建
index = pd.MultiIndex.from_product([['a', 'b'], [1, 2]], names=['letter', 'number'])
# 从 DataFrame 创建
df_index = pd.DataFrame({'letter': ['a', 'a', 'b', 'b'], 'number': [1, 2, 1, 2]})
index = pd.MultiIndex.from_frame(df_index)
多层索引操作 #
python
arrays = [
['a', 'a', 'b', 'b'],
[1, 2, 1, 2]
]
index = pd.MultiIndex.from_arrays(arrays, names=['letter', 'number'])
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=index)
# 查看索引层级
print(df.index.levels)
print(df.index.names)
# 选择数据
print(df.loc['a']) # 第一层
print(df.loc[('a', 1)]) # 多层
print(df.loc['a', 1]) # 等价
# 切片
print(df.loc['a':'b'])
print(df.loc[('a', 1):('b', 1)])
# xs 方法
print(df.xs('a', level='letter'))
print(df.xs(1, level='number'))
多层索引操作方法 #
python
# 交换层级
df = df.swaplevel('letter', 'number')
# 排序层级
df = df.sort_index(level='letter')
df = df.sort_index(level=0)
# 重置特定层
df = df.reset_index(level='letter')
# 设置新层级
df = df.set_index('A', append=True)
# 重命名层级
df = df.rename_axis(index={'letter': 'char'})
# 重命名层级值
df = df.rename(index={'a': 'A'}, level='letter')
多层列索引 #
python
# 创建多层列索引
columns = pd.MultiIndex.from_product([['A', 'B'], ['x', 'y']])
df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]], columns=columns)
# 选择列
print(df['A'])
print(df['A', 'x'])
print(df.loc[:, ('A', 'x')])
# 堆叠和展开
stacked = df.stack()
unstacked = stacked.unstack()
索引对齐 #
自动对齐 #
python
df1 = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
df2 = pd.DataFrame({'A': [4, 5, 6]}, index=['b', 'c', 'd'])
# 自动对齐
result = df1 + df2
print(result)
# A
# a NaN
# b 6.0
# c 8.0
# d NaN
reindex #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 重新索引
df = df.reindex(['a', 'b', 'c', 'd'])
# d 行会填充 NaN
# 填充缺失值
df = df.reindex(['a', 'b', 'c', 'd'], fill_value=0)
# 前向填充
df = df.reindex(['a', 'b', 'c', 'd'], method='ffill')
# 后向填充
df = df.reindex(['a', 'b', 'c', 'd'], method='bfill')
# 重索引列
df = df.reindex(columns=['A', 'B'])
align #
python
df1 = pd.DataFrame({'A': [1, 2]}, index=['a', 'b'])
df2 = pd.DataFrame({'A': [3, 4]}, index=['b', 'c'])
# 对齐两个 DataFrame
df1_aligned, df2_aligned = df1.align(df2)
# 指定填充方式
df1_aligned, df2_aligned = df1.align(df2, fill_value=0)
# 指定轴
df1_aligned, df2_aligned = df1.align(df2, axis=0)
索引性能优化 #
使用唯一索引 #
python
# 唯一索引查找更快
df = pd.DataFrame({'A': range(100000)})
df.index = df.index.astype(str) # 字符串索引
%timeit df.loc['50000'] # 快
# 重复索引查找较慢
df.index = [str(i % 100) for i in range(100000)]
%timeit df.loc['50'] # 慢
使用排序索引 #
python
# 排序索引查找更快
df = pd.DataFrame({'A': range(100000)})
df = df.sample(frac=1) # 打乱
%timeit df.loc[50000] # 未排序,较慢
df = df.sort_index()
%timeit df.loc[50000] # 排序后,更快
避免链式索引 #
python
# 不推荐:链式索引
df[df['A'] > 0]['B'] = 1 # SettingWithCopyWarning
# 推荐:loc
df.loc[df['A'] > 0, 'B'] = 1
索引实用技巧 #
检查索引 #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
# 检查索引是否单调
print(df.index.is_monotonic_increasing)
print(df.index.is_monotonic_decreasing)
# 检查索引是否唯一
print(df.index.is_unique)
# 检查索引是否有缺失值
print(df.index.hasnans)
索引去重 #
python
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'a', 'b'])
# 检查重复
print(df.index.duplicated())
# 去重
df = df[~df.index.duplicated()]
df = df[~df.index.duplicated(keep='last')]
df = df[~df.index.duplicated(keep=False)]
索引差集、交集、并集 #
python
idx1 = pd.Index([1, 2, 3, 4])
idx2 = pd.Index([3, 4, 5, 6])
# 差集
print(idx1.difference(idx2)) # Index([1, 2], dtype='int64')
# 交集
print(idx1.intersection(idx2)) # Index([3, 4], dtype='int64')
# 并集
print(idx1.union(idx2)) # Index([1, 2, 3, 4, 5, 6], dtype='int64')
# 对称差集
print(idx1.symmetric_difference(idx2)) # Index([1, 2, 5, 6], dtype='int64')
索引复制 #
python
# 复制索引
idx_copy = df.index.copy()
# 复制 DataFrame(包含索引)
df_copy = df.copy()
下一步 #
掌握了索引操作后,接下来学习 数据读写,了解如何读取和保存各种格式的数据!
最后更新:2026-04-04