Pandas数据分析-pandas数据框的多层索引

目录

前言

pandas数据框针对高维数据,也有多层索引的办法去应对。多层数据一般长这个样子

Pandas数据分析-pandas数据框的多层索引

可以看到AB两大列,下面又有xy两小列。 行有abc三行,又分为onetwo两小行。

在分组聚合的时候也会产生多层索引,下面演示一下。

导入包和数据:

import numpy as np 
import pandas as pd
df=pd.read_excel(\'team.xlsx\')

分组聚合:

df.groupby([\'team\',df.mean(1)>60]).count() #每组平均分大于60的人的个数

Pandas数据分析-pandas数据框的多层索引

 可以看到分为abcde五组,平均分大于60 的组员两小行。

创建多层索引

#序列中创建
arrays = [[1, 1, 2, 2], [\'red\', \'blue\', \'red\', \'blue\']]
index=pd.MultiIndex.from_arrays(arrays, names=(\'number\', \'color\'))
index

Pandas数据分析-pandas数据框的多层索引

pd.DataFrame([{\'a\':1, \'b\':2}], index=index)

Pandas数据分析-pandas数据框的多层索引

#来自元组创建
arrays = [[\'bar\', \'bar\', \'baz\', \'baz\', \'foo\', \'foo\', \'qux\', \'qux\'],
          [\'one\', \'two\', \'one\', \'two\', \'one\', \'two\', \'one\', \'two\']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=[\'first\', \'second\'])
pd.Series(np.random.randn(8), index=index)

Pandas数据分析-pandas数据框的多层索引

#可迭代对象的笛卡尔积,排列组合各种情况
numbers = [0, 1, 2]
colors = [\'green\', \'purple\']
index = pd.MultiIndex.from_product([numbers, colors],names=[\'number\', \'color\'])
pd.Series(np.random.randn(6), index=index)

Pandas数据分析-pandas数据框的多层索引

#来自 DataFrame
df = pd.DataFrame([[\'bar\', \'one\'], [\'bar\', \'two\'],
                   [\'foo\', \'one\'], [\'foo\', \'two\']],
                  columns=[\'first\', \'second\'])
\'\'\'
  first second
0   bar    one
1   bar    two
2   foo    one
3   foo    two
\'\'\'
index = pd.MultiIndex.from_frame(df)
pd.Series(np.random.randn(4), index=index)

Pandas数据分析-pandas数据框的多层索引

 多层索引操作

index_arrays = [[1, 1, 2, 2], [\'男\', \'女\', \'男\', \'女\']]
columns_arrays = [[\'2020\', \'2020\', \'2021\', \'2021\'],
                  [\'上半年\', \'下半年\', \'上半年\', \'下半年\',]]
index = pd.MultiIndex.from_arrays(index_arrays,names=(\'班级\', \'性别\'))
columns = pd.MultiIndex.from_arrays(columns_arrays,names=(\'年份\', \'学期\'))
df = pd.DataFrame([(88,99,88,99),(77,88,97,98),
                   (67,89,54,78),(34,67,89,54)],columns=columns, index=index)
df

Pandas数据分析-pandas数据框的多层索引

 索引名称的查看

#索引名称的查看:
df.index # 索引, 是一个 MultiIndex
df.columns # 引索引,也是一个 MultiIndex
# 查看行索引的名称
df.index.names # FrozenList([\'班级\', \'性别\'])
# 查看列索引的名称
df.columns.names # FrozenList([\'年份\', \'学期\'])

 索引的层级

#索引的层级:
df.index.nlevels # 层级数   2
df.index.levels # 行的层级    # FrozenList([[1, 2], [\'女\', \'男\']])
df.columns.levels # 列的层级  # FrozenList([[\'2020\', \'2021\'], [\'上半年\', \'下半年\']])
df[[\'2020\',\'2021\']].index.levels # 筛选后的层级  # FrozenList([[1, 2], [\'女\', \'男\']])

 索引内容的查看

#索引内容的查看:
# 获取索引第2层内容
df.index.get_level_values(1)
# Index([\'男\', \'女\', \'男\', \'女\'], dtype=\'object\', name=\'性别\')
# 获取列索引第1层内容
df.columns.get_level_values(0)
# Index([\'2020\', \'2020\', \'2021\', \'2021\'], dtype=\'object\', name=\'年份\')
 
# 按索引名称取索引内容
df.index.get_level_values(\'班级\')
# Int64Index([1, 1, 2, 2], dtype=\'int64\', name=\'班级\')
df.columns.get_level_values(\'年份\')
# Index([\'2020\', \'2020\', \'2021\', \'2021\'], dtype=\'object\', name=\'年份\')
 
# 多层索引的数据类型,1.3.0+
df.index.dtypes

 #排序

# 使用索引名可进行排序,可以指定具体的列
df.sort_values(by=[\'性别\', (\'2020\',\'下半年\')])
df.index.reorder_levels([1,0])  # 等级顺序,互换
df.index.set_codes([1, 1, 0, 0], level=\'班级\') # 设置顺序
df.index.sortlevel(level=0, ascending=True)   # 按指定级别排序
df.index.reindex(df.index[::-1]) # 更换顺序,或者指定一个顺序

 相关操作转换:

df.index.to_numpy() # 生成一个笛卡尔积的元组对列表
# array([(1, \'男\'), (1, \'女\'), (2, \'男\'), (2, \'女\')], dtype=object)
df.index.remove_unused_levels() # 返回没有使用的层级
df.swaplevel(0, 2) # 交换索引
df.to_frame() # 转为 DataFrame
idx.set_levels([\'a\', \'b\'], level=\'bar\') # 设置新的索引内容
idx.set_levels([[\'a\', \'b\', \'c\'], [1, 2, 3, 4]], level=[0, 1])
idx.to_flat_index()   # 转为元组对列表
df.index.droplevel(0) # 删除指定等级
df.index.get_locs((2, \'女\'))  # 返回索引的位置

数据查询

#查询指定行
df.loc[1] #一班的
df.loc[(1, \'男\')] # 一年级男
df.loc[1:2] # 一二两年级数据

Pandas数据分析-pandas数据框的多层索引

#查询指定列
df[\'2020\'] # 整个一级索引下
df[(\'2020\',\'上半年\')] # 指定二级索引
df[\'2020\'][\'上半年\'] # 同上

Pandas数据分析-pandas数据框的多层索引

#行列综合  slice(None)表示本层所有内容
df.loc[(1, \'男\'), \'2020\'] # 只显示2020年一年级男
df.loc[:, (slice(None), \'下半年\')] # 只看下半年的
df.loc[(slice(None), \'女\'),:] # 只看女生
df.loc[1, (slice(None)),:] # 只看1班
df.loc[:, (\'2020\', slice(None))] # 只看 2020 年的

Pandas数据分析-pandas数据框的多层索引

Pandas数据分析-pandas数据框的多层索引

#查询指定条件

#和单层索引的数据查询一样,不过在选择列上要按多层的规则。
df[df[(\'2020\',\'上半年\')] > 80]

Pandas数据分析-pandas数据框的多层索引

#pd.IndexSlice切片使用:
 
idx = pd.IndexSlice
idx[0]               # 0
idx[:]               # slice(None, None, None)
idx[0,\'x\']           # (0, \'x\')
idx[0:3]             # slice(0, 3, None)
idx[0.1:1.5]         # slice(0.1, 1.5, None)
idx[0:5,\'x\':\'y\']     # (slice(0, 5, None), slice(\'x\', \'y\', None))
#查询应用:
idx = pd.IndexSlice
df.loc[idx[:,[\'男\']],:] # 只显示男
df.loc[:,idx[:,[\'上半年\']]] # 只显示上半年
 
#df.xs()
df.xs((1, \'男\')) # 一年级男生
df.xs(\'2020\', axis=1) # 2020 年
df.xs(\'男\', level=1) # 所有男生

 数据分组

df.groupby(level=0).sum()
df.groupby(level=\'性别\').sum()
df.sum(level=\'班级\') # 也可以直接统计

Pandas数据分析-pandas数据框的多层索引

df.groupby(level=[\'性别\', \'班级\']).sum()

Pandas数据分析-pandas数据框的多层索引

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容