mysql 多重索引_dataframe 中的多层索引

1、生成两层行索引、列索引的样本数据

1)生成 DataFrame

import pandas as pd

import numpy as np

pd.set_option('display.max_columns', 1000)

pd.set_option('display.width', 1000)

pd.set_option('display.max_colwidth', 1000)

df = pd.DataFrame(np.random.randint(80,150,size=(9, 9)),

columns=pd.MultiIndex.from_product([['last year', 'this year', 'next year'],['price', 'height', 'weight']]),

index=pd.MultiIndex.from_product([['xiaoming', 'lili', 'xiaohong'],['chicken', 'dog', 'cat']]))

df

Out[67]:

last year this year next year

price height weight price height weight price height weight

xiaoming chicken 148 137 121 119 95 98 90 118 110

dog 88 143 117 100 86 95 82 122 142

cat 120 93 145 137 148 136 110 99 88

lili chicken 146 86 90 91 116 134 124 116 94

dog 103 144 141 131 104 108 90 87 121

cat 120 119 88 102 129 113 131 118 98

xiaohong chicken 132 146 103 128 98 143 126 81 136

dog 129 92 99 103 84 116 99 100 85

cat 131 125 129 146 104 119 135 115 117

2)生成 Series

ser = pd.Series(np.random.randint(0,150,size=6),

index=pd.MultiIndex.from_product([['xiaoming', 'lili'],['chicken', 'dog', 'cat']]))

ser

Out[23]:

xiaoming chicken 135

dog 94

cat 74

lili chicken 24

dog 142

cat 4

dtype: int32

2、索引使用总体原则

1)在进行多重索引操作之前要对索引进行排序

df2 = df.sort_index()

df2

Out[16]:

last year this year next year

price height weight price height weight price height weight

lili cat 120 119 88 102 129 113 131 118 98

chicken 146 86 90 91 116 134 124 116 94

dog 103 144 141 131 104 108 90 87 121

xiaohong cat 131 125 129 146 104 119 135 115 117

chicken 132 146 103 128 98 143 126 81 136

dog 129 92 99 103 84 116 99 100 85

xiaoming cat 120 93 145 137 148 136 110 99 88

chicken 148 137 121 119 95 98 90 118 110

dog 88 143 117 100 86 95 82 122 142

2)索引的顺序一般是先外层,再内层

3、 索引与切片 —— Series

1)显式

从最外层开始索引, 不能直接索引最内侧层索引。

ser['lili', 'dog']

Out[27]: 142

或者

ser.loc['lili', :]

Out[28]:

chicken 24

dog 142

cat 4

dtype: int32

2)隐式

不区分层级索引。

ser.iloc[[1,3,4]]

Out[29]:

xiaoming dog 94

lili chicken 24

dog 142

dtype: int32

4、索引与切片 —— DataFrame

1)列索引:直接用列名索引

# 以下几种用法,效果相同

df['last year']['price']

df['last year', 'price']

df[('last year', 'price')]

df.iloc[:, 0]

Out[30]:

lili cat 120

chicken 146

dog 103

xiaohong cat 131

chicken 132

dog 129

xiaoming cat 120

chicken 148

dog 88

Name: (last year, price), dtype: int32

2)列切片

# 显式

df.loc[:, 'this year']

# 隐式

df.iloc[:, 3:6]

Out[45]:

this year

price height weight

lili cat 109 138 91

chicken 106 111 103

dog 119 106 84

xiaohong cat 112 125 135

chicken 119 85 129

dog 114 90 102

xiaoming cat 111 117 89

chicken 95 99 113

dog 135 90 136

3)行索引

#外层[ ] 表示返回原数据类型(df),否则返回 series

# 显式

df.loc[[('lili', 'dog')]]

# 隐式

df.iloc[[0]]

Out[31]:

last year this year

price height weight price height weight

lili dog 140 147 92 135 92 94

4)行切片

df.loc['lili':'xiaohong']

Out[32]:

last year this year next year

price height weight price height weight price height weight

lili cat 120 121 106 109 138 91 85 111 114

chicken 117 124 93 106 111 103 133 115 140

dog 107 112 141 119 106 84 138 119 93

xiaohong cat 102 93 80 112 125 135 101 115 94

chicken 83 107 86 119 85 129 85 127 139

dog 116 110 103 114 90 102 90 130 117

5、pd.IndexSlice 的用法

多层索引的切片,跟单层索引的不大一样,比如:

In[45]: df.loc[[:, 'dog'], [:, 'price']]

File "", line 1

df.loc[[:, 'dog'], [:, 'price']]

^

SyntaxError: invalid syntax

此时需要用 IndexSlice 实现单层索引的使用习惯。

In[46]:

idx = pd.IndexSlice

df.loc[idx[:, 'dog'], idx[:, 'price']]

Out[46]:

last year this year next year

price price price

lili dog 107 119 138

xiaohong dog 116 114 90

xiaoming dog 115 135 83

6、pd.xs() 的索引与切片

优点:pd.xs() 能跳过最外层索引,直接从指定层按索引取数据。

缺点

1)不能通过它进行值的设定。

2)同一级别只能索引单值。

pd.xs() 的语法是

DataFrame.xs(key, axis=0, level=None, drop_level=True)

其中:

key : label 或 tuple 类型的 label

axis : {0 或 ‘index’, 1 或 ‘columns’}, 默认 0

level : 索引所在的层级,默认为前n层(n=1或len(key)),如果 key 部分包含在多索引中,请指示在哪个层级上使用。层级可以通过 label 或 position来引用。

drop_level : bool, 默认True。如果为False,返回与自己级别相同的对象。

返回:

在原始 Series 或者 DataFrame 中按指定索引得到的横截面数据 (也是 Series 或者 DataFrame 类型)

# 基本使用方法

In[137]: df.xs(('xiaoming', 'cat))

Out[137]:

last year price 115

height 134

weight 100

this year price 111

height 117

weight 89

next year price 133

height 85

weight 83

Name: (xiaoming, cat), dtype: int32

# 同一级别只能索引单值,索引多值会报错

In[46]: df.xs(('xiaoming', 'lili'))

KeyError: ('xiaoming', 'lili')

# 取出所有行索引含 'cat' 的数据

In[47]: df.xs('cat', axis=0, level=1)

Out[47]:

last year this year next year

price height weight price height weight price height weight

lili 107 112 141 119 106 84 138 119 93

xiaohong 116 110 103 114 90 102 90 130 117

xiaoming 115 140 121 135 90 136 83 88 127

# 取出所有行索引含 'cat' ,列索引含 'height' 的数据

In[130]: df.xs('cat', axis=0, level=1).xs('height', axis=1, level=1)

Out[130]:

last year this year next year

lili 121 138 111

xiaohong 93 125 115

xiaoming 134 117 85

7、索引转换

列索引转成行索引,用参数 level 指定要转的索引层级,默认是最内层。

df.stack()

行索引转成列索引,用参数 level 指定要转的索引层级,默认是最内层。

df.unstack()

相关应用有

1)Series 转 DataFrame

In[131]: ser.unstack()

Out[131]:

cat chicken dog

lili 4 24 142

xiaoming 74 135 94

2)DataFrame 转 Series

In[136]: df.stack().stack()

Out[136]:

lili cat height last year 121

next year 111

this year 138

price last year 120

next year 85

...

xiaoming dog price next year 83

this year 135

weight last year 121

next year 127

this year 136

Length: 81, dtype: int32

3)多层索引转单层索引

In[146]: df.stack().stack().reset_index()

Out[146]:

level_0 level_1 level_2 level_3 0

0 lili cat height last year 121

1 lili cat height next year 111

2 lili cat height this year 138

3 lili cat price last year 120

4 lili cat price next year 85

.. ... ... ... ... ...

76 xiaoming dog price next year 83

77 xiaoming dog price this year 135

78 xiaoming dog weight last year 121

79 xiaoming dog weight next year 127

80 xiaoming dog weight this year 136

4)多层索引在不同轴上的转换

# 最外层的列索引转到行索引

In[156]: df.stack(level=0)

Out[156]:

height price weight

lili cat last year 121 120 106

next year 111 85 114

this year 138 109 91

chicken last year 124 117 93

next year 115 133 140

this year 111 106 103

dog last year 112 107 141

next year 119 138 93

this year 106 119 84

xiaohong cat last year 93 102 80

next year 115 101 94

this year 125 112 135

...

# 最外层的行索引转到列索引上

In[159]: df.unstack(level=0)

Out[159]:

last year ... next year

price height ... height weight

lili xiaohong xiaoming lili xiaohong ... xiaohong xiaoming lili xiaohong xiaoming

cat 120 102 115 121 93 ... 115 85 114 94 83

chicken 117 83 138 124 107 ... 127 89 140 139 149

dog 107 116 115 112 110 ... 130 88 93 117 127

[3 rows x 27 columns]

5)多层索引在同一个轴内的转换

df.swaplevel(axis=0)

Out[148]:

last year this year next year

price height weight price height weight price height weight

cat lili 120 121 106 109 138 91 85 111 114

chicken lili 117 124 93 106 111 103 133 115 140

dog lili 107 112 141 119 106 84 138 119 93

cat xiaohong 102 93 80 112 125 135 101 115 94

chicken xiaohong 83 107 86 119 85 129 85 127 139

dog xiaohong 116 110 103 114 90 102 90 130 117

cat xiaoming 115 134 100 111 117 89 133 85 83

chicken xiaoming 138 96 82 95 99 113 99 89 149

dog xiaoming 115 140 121 135 90 136 83 88 127

df.swaplevel(axis=1)

Out[150]:

price height weight price height weight price height weight

last year last year last year this year this year this year next year next year next year

lili cat 120 121 106 109 138 91 85 111 114

chicken 117 124 93 106 111 103 133 115 140

dog 107 112 141 119 106 84 138 119 93

xiaohong cat 102 93 80 112 125 135 101 115 94

chicken 83 107 86 119 85 129 85 127 139

dog 116 110 103 114 90 102 90 130 117

xiaoming cat 115 134 100 111 117 89 133 85 83

chicken 138 96 82 95 99 113 99 89 149

dog 115 140 121 135 90 136 83 88 127

8、对索引的操作

1)给索引起名

In[151]: df.index.names

Out[151]: FrozenList([None, None])

In[152]:

df.index.names = ['puple', 'animal']

df

Out[152]:

Out[165]:

last year this year next year

price height weight price height weight price height weight

puple animal

lili cat 120 121 106 109 138 91 85 111 114

chicken 117 124 93 106 111 103 133 115 140

dog 107 112 141 119 106 84 138 119 93

xiaohong cat 102 93 80 112 125 135 101 115 94

chicken 83 107 86 119 85 129 85 127 139

dog 116 110 103 114 90 102 90 130 117

xiaoming cat 115 134 100 111 117 89 133 85 83

chicken 138 96 82 95 99 113 99 89 149

dog 115 140 121 135 90 136 83 88 127

2)取指定层级的索引值

In[160]: df.index.get_level_values(0)

或者

In[160]: df.index.get_level_values('')

Out[160]: Index(['lili', 'lili', 'lili', 'xiaohong', 'xiaohong', 'xiaohong', 'xiaoming', 'xiaoming', 'xiaoming'], dtype='object')

3)索引排序

# 将第二层列索引按降序排列

In[166]: df.sort_index(axis=1, level=1, ascending=False)

Out[166]:

this year next year last year this year next year last year this year next year last year

weight weight weight price price price height height height

puple animal

lili cat 91 114 106 109 85 120 138 111 121

chicken 103 140 93 106 133 117 111 115 124

dog 84 93 141 119 138 107 106 119 112

xiaohong cat 135 94 80 112 101 102 125 115 93

chicken 129 139 86 119 85 83 85 127 107

dog 102 117 103 114 90 116 90 130 110

xiaoming cat 89 83 100 111 133 115 117 85 134

chicken 113 149 82 95 99 138 99 89 96

dog 136 127 121 135 83 115 90 88 140

参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值