1、创建多层索引
可以使用pd.MultiIndex
和set_index()
创建多层索引。
1)set_index()
使用set_index()
可以使用多个参数来实现不同的多层索引(层次化索引)操作。
参考说明:
参数 | 描述 |
keys | 用于创建索引的列名或列名列表,可以是单个列名或多个列名。 |
drop | 布尔值,指定设置索引后是否删除原来的列,默认为 True(删除)。 |
append | 布尔值,指定是否将新索引添加到现有索引,默认为 False。 |
verify_integrity | 布尔值,用于检查新生成的索引是否有重复项,默认为 False。 |
level | 用于从多层索引中删除级别的整数或级别名。 |
inplace | 布尔值,指定是否在原地修改 DataFrame,默认为 False。 |
col_level | 用于确定将列插入到多层索引的哪个级别, 适用于具有多层列的 DataFrame。 |
col_fill | 创建多层索引时,用于填充其他级别的名称。 |
使用示例:
import pandas as pd
# 创建示例 DataFrame
df = pd.DataFrame({
'A': ['foo', 'bar', 'baz', 'foo'],
'B': ['one', 'one', 'two', 'two'],
'C': ['x', 'y', 'x', 'y'],
'D': [1, 3, 2, 4]
})
# 使用 set_index() 示例
# 设置单列为索引
single_index_df = df.set_index('A')
# 设置多列为多层索引
multi_index_df = df.set_index(['A', 'B'])
# 设置索引并保留原始列
index_with_original_df = df.set_index('A', drop=False)
# 添加到现有索引
append_index_df = df.set_index('C', append=True)
# 打印创建的 DataFrame 示例
print(single_index_df, multi_index_df, index_with_original_df, append_index_df)
2)pd.MultiIndex
pd.MultiIndex
用于创建多层(层次化)索引,它提供了几个参数来定制索引。使用 pd.MultiIndex
可以创建强大的多层索引结构,这在处理和分析具有复杂层次结构的数据时非常有用。
参数说明:
参数 | 描述 |
levels | 列表的列表,每个内部列表包含索引的唯一值, 代表不同的索引层级。 |
codes | 列表的列表,每个内部列表包含整数代码, 这些代码指向 levels 中相应级别的值。 |
labels | (已弃用)与 codes 类似, 但已在新版本的 Pandas 中弃用。 |
names | 索引层级的名称列表, 有助于标识每个层级。 |
sortorder | 一个整数,用于确定多索引级别的排序顺序。 |
copy | 布尔值,用于指定是否复制 levels 和 codes, 默认为 |
verify_integrity | 布尔值,用于检查新的 MultiIndex 是否有效,默认为 |
dtype | 设置索引数据类型。 |
使用示例:
import pandas as pd
# 通过列表的列表创建 MultiIndex
multi_index_from_arrays = pd.MultiIndex.from_arrays([['A', 'A', 'B', 'B'], [1, 2, 1, 2]], names=['letter', 'number'])
# 通过元组的列表创建 MultiIndex
multi_index_from_tuples = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 1), ('B', 2)], names=['letter', 'number'])
# 通过产品创建 MultiIndex
multi_index_from_product = pd.MultiIndex.from_product([['A', 'B'], [1, 2]], names=['letter', 'number'])
# 直接使用 pd.MultiIndex 构造函数创建 MultiIndex
multi_index_direct = pd.MultiIndex(levels=[['A', 'B'], [1, 2]], codes=[[0, 0, 1, 1], [0, 1, 0, 1]], names=['letter', 'number'])
# 创建一个示例 DataFrame 使用 MultiIndex
df = pd.DataFrame({'data': range(4)}, index=multi_index_from_arrays)
# 打印创建的 MultiIndex 和 DataFrame 示例
print(multi_index_from_arrays, multi_index_from_tuples, multi_index_from_product, multi_index_direct, df)
2、选择数据
当使用多层索引(MultiIndex)时,loc
和 iloc
方法都可以用于选择和切片数据,但它们的使用方式略有不同。loc
主要用于基于标签的索引。当处理多层索引时,可以传递一个元组来指定每层的索引值。iloc
用于基于整数的位置索引,它忽略索引的实际标签。
参考文档:Python pandas dataframe iloc 和 loc 的用法及区别
import pandas as pd
index = pd.MultiIndex.from_tuples(
[('A', 1), ('A', 2), ('B', 1), ('B', 2)],
names=['letter', 'number']
)
df = pd.DataFrame({'data': [10, 20, 30, 40]}, index=index)
# 使用 loc 方法进行选择和切片
single_element_loc = df.loc[('A', 1)]
slice_loc = df.loc['A']
specific_column_loc = df.loc[('A', 1), 'data']
multiple_index_loc = df.loc[[('A', 1), ('B', 2)]]
# 使用 iloc 方法进行选择和切片
single_element_iloc = df.iloc[0]
slice_iloc = df.iloc[0:2]
specific_column_iloc = df.iloc[0, 0]
# 布尔索引和 iloc 一起使用不太常见,通常使用 loc
print(single_element_loc, slice_loc, specific_column_loc, multiple_index_loc, single_element_iloc, slice_iloc, specific_column_iloc)
3、交叉切片
Pandas 中,交叉切片(cross-section)是一种高级的数据操作技术,特别适用于多层索引的场景。它允许你选择特定层级的特定键值,而不考虑其他层级。pd.IndexSlice用于对多层索引进行更复杂的切片。pd.IndexSlice
的强大之处在于它提供了一种更为直观和灵活的方式来切片多层索引的 Pandas 对象。通过使用它,可以更精确地选择数据的子集,特别是在处理复杂的数据结构时。pd.IndexSlice
经常与.loc
或.iloc
索引器结合使用。
import pandas as pd
import numpy as np
# 创建示例多层索引DataFrame
arrays = [np.array(['bar', 'bar', 'baz', 'baz']),
np.array(['one', 'two', 'one', 'two'])]
index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])
df = pd.DataFrame(np.random.randn(4, 2), index=index, columns=['A', 'B'])
# 使用IndexSlice选择数据
idx = pd.IndexSlice
slice_data1 = df.loc[idx['bar', 'one'], :]
slice_data2 = df.loc[idx[['bar', 'baz'], ['one']], :]
slice_data3 = df.loc[idx['bar':'baz', 'one'], :]
slice_data4 = df.loc[idx[:, 'one':'two'], :]
# 打印原始DataFrame和使用IndexSlice的结果
print("原始DataFrame:\n", df)
print("\nIndexSlice选择 - 'bar', 'one':\n", slice_data1)
print("\nIndexSlice选择 - ['bar', 'baz'], ['one']:\n", slice_data2)
print("\nIndexSlice选择 - 'bar':'baz', 'one':\n", slice_data3)
print("\nIndexSlice选择 - :, 'one':'two':\n", slice_data4)
4、重塑数据
Pandas 中,处理具有多层索引的 DataFrame
时,你可能需要重塑数据。这可以通过多种方式实现,重塑数据常使用用stack
、unstack
、pivot
、melt
方法。
参数文档:
Python pandas.DataFrame.stack函数方法的使用
Python pandas.DataFrame.unstack函数方法的使用
Python pandas.DataFrame.pivot函数方法的使用
Python pandas.DataFrame.pivot_table函数方法的使用
Python pandas.DataFrame.melt函数方法的使用
使用示例:
import numpy as np
import pandas as pd
# 示例 DataFrame
df = pd.DataFrame({
'A': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
'B': ['one', 'one', 'two', 'two', 'one', 'one'],
'C': ['small', 'large', 'large', 'small', 'small', 'large'],
'D': [1, 2, 2, 3, 3, 4],
'E': [2, 4, 5, 5, 6, 6]
})
# 使用 stack 方法
stacked = df.set_index(['A', 'B', 'C']).stack()
# 使用 unstack 方法
unstacked = stacked.unstack()
# 使用 pivot 方法
df1 = pd.DataFrame({
'date': ['2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02'],
'city': ['New York', 'Los Angeles', 'New York', 'Los Angeles'],
'temperature': [32, 75, 30, 77],
'humidity': [80, 40, 82, 43]
})
# 使用 pivot 方法重塑数据
pivot_df = df1.pivot(index='date', columns='city', values='temperature')
print(pivot_df)
# 使用 pivot_table 方法
pivot_table = df.pivot_table(values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum)
# 使用 melt 方法
melted = df.melt(id_vars=['A', 'B'], value_vars=['D', 'E'])
# 打印结果
print(stacked, unstacked, pivot_table, melted)
5、聚合操作
Pandas 中,当使用多层索引(MultiIndex)的 DataFrame
或 Series
进行聚合操作时,可以对数据的不同层级进行分组和汇总。Pandas 提供了多种方法来执行这些聚合操作,常使用groupby
、agg
和 transform
方法进行聚合操作。
参数文档:
Python pandas.DataFrame.groupby函数方法的使用
Python pandas.DataFrame.agg函数方法的使用
Python pandas.DataFrame.transform函数方法的使用
使用示例:
import pandas as pd
import numpy as np
# 示例 DataFrame
df = pd.DataFrame({
'A': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
'B': ['one', 'one', 'two', 'two', 'one', 'one'],
'C': [1, 2, 3, 4, 5, 6],
'D': [7, 8, 9, 10, 11, 12]
}).set_index(['A', 'B'])
# 使用 groupby 进行聚合
grouped_sum = df.groupby(level='A').sum()
grouped_agg = df.groupby(level='A').agg({'C': 'sum', 'D': 'mean'})
# 使用 agg 方法进行多函数聚合
agg_functions = df.agg(['sum', 'mean'])
# 使用 transform 方法进行数据转换
transformed = df.groupby(level='A').transform('mean')
# 打印结果
print(grouped_sum, grouped_agg, agg_functions, transformed)