python

Python--MultiIndex多层次索引学习

2019-06-13  本文已影响0人  李小李的路

Python3 pandas.MultiIndex 概述

入门级demo学习

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 10:11
# @Author  : LiYahui
# @Description : python multiindex demo
import pandas as pd
import numpy as np
data = pd.Series(np.random.randn(10),
              index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
                     [1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
print("----------print data---------------")
print(data)
'''
a  1   -0.902378
   2   -1.512923
   3   -1.082350
b  1   -0.900975
   2   -1.723988
   3   -0.791613
c  1   -1.631530
   2    2.290227
d  2    0.530892
   3    1.199453
dtype: float64
'''
print("----------print data.index-------------")
print(data.index)
'''
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
           codes=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])

'''
print("----------print data.index.levels[0]----------------")
print(data.index.levels[0])
'''
Index(['a', 'b', 'c', 'd'], dtype='object')
'''
print("----------print data.index.levels[1]----------------")
print(data.index.levels[1])
'''
Int64Index([1, 2, 3], dtype='int64')
'''

MultiIndex创建的方式

第一种

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 10:52
# @Author  : LiYahui
# @Description : MultiIndex demo
import pandas as pd
import numpy as np

# 创建多层索引的第一种方式
# 创建Series对象,具有单层索引。
s1 = pd.Series([1, 2, 3], index=["a", "b", "c"])
print(s1)
'''
a    1
b    2
c    3
dtype: int64
'''

# 创建多层索引。多层索引需要一个二维的数组,每个元素(一维数组)来指定每个层级的索引。顺序
# 由高层(左边)到底层(右边)。
s2 = pd.Series([1, 2, 3, 4], index=[["a", "a", "b", "b"], ["c", "d", "e", "f"], ["m", "m", "k", "t"]])
print(s2)
'''
a  c  m    1
   d  m    2
b  e  k    3
   f  t    4
dtype: int64
'''
print("-------df--------")
df = pd.DataFrame(np.random.random(size=(4, 4)), index=[["上半年", "上半年", "下半年", "下半年"],
                                                        ["第一季度", "第二季度", "第三季度", "第四季度"]],
                  columns=[["水果", "水果", "蔬菜", "蔬菜"], ["苹果", "葡萄", "白菜", "萝卜"]])
print(df)
'''
                水果                  蔬菜          
                苹果        葡萄        白菜        萝卜
上半年 第一季度  0.356637  0.358602  0.402864  0.550727
    第二季度  0.963110  0.010293  0.378511  0.051015
下半年 第三季度  0.098882  0.394281  0.554502  0.676566
    第四季度  0.828770  0.506423  0.681128  0.542206
'''
print(df.index)
'''
MultiIndex(levels=[['上半年', '下半年'], ['第一季度', '第三季度', '第二季度', '第四季度']],
           codes=[[0, 0, 1, 1], [0, 2, 1, 3]])
'''
print(df.columns)
'''
MultiIndex(levels=[['水果', '蔬菜'], ['白菜', '苹果', '萝卜', '葡萄']],
           codes=[[0, 0, 1, 1], [1, 3, 0, 2]])
'''
# 如果是单层索引,我们可以通过索引对象的name属性来设置索引的名称。
s2 = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
s2.index.name = "索引名称"
print("--------s2----------")
print(s2)
'''
索引名称
a    1
b    2
c    3
d    4
dtype: int64
'''
# 对于多层索引,也可以设置索引的名称,此时,设置名称的属性为names(通过一维数组来设置)。
# 每层索引都具有名称。
# 修改df的索引
df.index.names = ["年度", "季度"]
df.columns.names = ["大类别", "小类别"]
print(df)
'''
大类别             水果                  蔬菜          
小类别             苹果        葡萄        白菜        萝卜
年度  季度                                          
上半年 第一季度  0.078253  0.961293  0.770540  0.267522
    第二季度  0.845138  0.239290  0.208779  0.347256
下半年 第三季度  0.869534  0.148100  0.046563  0.753004
    第四季度  0.926966  0.305344  0.379041  0.467218
'''

第二种

from_product相对于前两个方法而言,实现相对简单,但是,也存在局限。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 11:13
# @Author  : LiYahui
# @Description :multiindex demo
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.random(size=(4, 4)), index=[["上半年", "上半年", "下半年", "下半年"],
                                                        ["第一季度", "第二季度", "第三季度", "第四季度"]],
                  columns=[["水果", "水果", "蔬菜", "蔬菜"], ["苹果", "葡萄", "白菜", "萝卜"]])
print(df)
'''
                水果                  蔬菜          
                苹果        葡萄        白菜        萝卜
上半年 第一季度  0.645330  0.408014  0.121088  0.106337
    第二季度  0.671892  0.212711  0.792635  0.031329
下半年 第三季度  0.063841  0.513930  0.342464  0.885220
    第四季度  0.091936  0.745129  0.905859  0.760001
'''
# 创建多层索引的第二种方式
# ------------from_arrays-------------------
# from_arrays 参数为一个二维数组,每个元素(一维数组)来分别制定每层索引的内容。
mindex_arrsys = pd.MultiIndex.from_arrays([["上半年", "上半年", "下半年", "下半年"], ["1季度", "2季度", "3季度", "4季度"]])
df2 = pd.DataFrame(np.random.random(size=(4, 4)), index=mindex_arrsys)
print(df2)
'''
                0         1         2         3
上半年 1季度  0.578044  0.636138  0.497155  0.389131
    2季度  0.195453  0.623200  0.769118  0.637451
下半年 3季度  0.562462  0.629691  0.684193  0.981682
    4季度  0.873525  0.489149  0.883518  0.252548
'''
# ------------from_tuples-------------------
# from_tuples 参数为一个(嵌套的)可迭代对象,元素为元祖类型。元祖的格式为:(高层索引内容,低层索引内容)
mindex_tuples = pd.MultiIndex.from_tuples([("上半年", "1季度"), ("上半年", "2季度"), ("下半年", "3季度"), ("下半年", "4季度")])
df3 = pd.DataFrame(np.random.random(size=(4, 4)), index=mindex_tuples)
print(df3)
'''
                0         1         2         3
上半年 1季度  0.843825  0.242793  0.132814  0.024581
    2季度  0.404961  0.870869  0.134744  0.220976
下半年 3季度  0.196361  0.074073  0.588173  0.181438
    4季度  0.936489  0.246351  0.941209  0.144210
'''
# ------------from_products-------------------
# 使用笛卡尔积的方式来创建多层索引。参数为嵌套的可迭代对象。结果为使用每个一维数组中的元素与其他一维数组中的元素来生成
# 索引内容。
mindex_products = pd.MultiIndex.from_product([["a", "b"], ["c", "d"]], names=["outer", "inner"])
print(mindex_products)
'''
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])
'''
print(pd.MultiIndex.from_arrays([["a", "a", "b", "b"], ["c", "d", "c", "d"]]))
'''
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
'''
print(pd.MultiIndex.from_arrays([["a", "a", "b"], ["c", "d", "d"]]))
'''
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1], [0, 1, 1]])
'''

# MultiIndex的三个类方法,可以创建MultiIndex类型的对象。三种方式相比,第三种方式(笛卡尔积的方式)更加简便,但是,
# 其也具有一定的局限:两两组合必须都存在,否则,就不能使用这种方式。
# 在创建多层索引对象时,可以通过names参数来指定每个索引层级的名称。

df4 = pd.DataFrame(np.random.random(size=(4, 4)),index=mindex_products)
print(df4)
print(df4.index)
'''
                    0         1         2         3
outer inner                                        
a     c      0.213218  0.561547  0.224423  0.764169
      d      0.296970  0.557486  0.809295  0.300886
b     c      0.134809  0.111138  0.619714  0.223240
      d      0.707181  0.872395  0.800698  0.676075
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])
'''
# 还有第三种方式(因为繁琐,所以不用),最直接的方式:
mindex = pd.MultiIndex(levels=[['a', 'b'], ['c', 'd']],
                       codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
                       names=['outer', 'inner'])
print(mindex)
'''
MultiIndex(levels=[['a', 'b'], ['c', 'd']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=['outer', 'inner'])
'''

多层索引操作

Series多层索引

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 11:28
# @Author  : LiYahui
# @Description : 位置选择
import pandas as pd

s = pd.Series([1, 2, 3, 4], index=[["a", "a", "b", "b"], ["c", "d", "e", "f"]])
print(s)
'''
a  c    1
   d    2
b  e    3
   f    4
dtype: int64
'''
# 多层索引的优势,可以一次获取一组元素(值)
print(s.loc["a"])
'''
c    1
d    2
dtype: int64
'''
# 也可以沿着索引层次进行访问。
print(s.loc["a", "d"]) # 访问指定坐标的元素值
'''
2
'''
# 通过位置索引访问元素,与多层索引没有任何关系。
print(s.iloc[0])
'''
1
'''

# 切片
print(s.loc["a":"b"])
'''
a  c    1
   d    2
b  e    3
   f    4
dtype: int64
'''
# 行index上的序号类型的切片
print(s.iloc[0:2])
'''
a  c    1
   d    2
b  e    3
   f    4
dtype: int64
'''

DataFrame多层索引

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 11:28
# @Author  : LiYahui
# @Description : 位置选择
import pandas as pd
data=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
df=pd.DataFrame(data)
print(df)
'''
    0   1   2   3
0   1   2   3   4
1   5   6   7   8
2   9  10  11  12
3  13  14  15  16
'''
# 指定行索引
df.index=[["a", "a", "b", "b"], ["c", "d", "c", "d"]]
# 指定列索引
df.columns=[["x", "x", "y", "y"], ["z", "u", "z", "u"]]
print("-----------指定行和列索引之后的数据值---------------")
print(df)
'''
      x       y    
      z   u   z   u
a c   1   2   3   4
  d   5   6   7   8
b c   9  10  11  12
  d  13  14  15  16
'''
print('-------df.loc["a"]------------')
print(df.loc["a"]) # 对应的外层索引的切片
'''
   x     y   
   z  u  z  u
c  1  2  3  4
d  5  6  7  8
'''
print('--------df.loc["a", "c"]-----------')
print(df.loc["a", "c"])   #取的是对应的行数据
'''
x  z    1
   u    2
y  z    3
   u    4
'''
print('------df["x", "z"])--------')
print(df["x", "z"]) #取的是列数据
'''
a  c     1
   d     5
b  c     9
   d    13
Name: (x, z), dtype: int64
'''

# 通过位置访问元素与是否多层索引无关。
print('----------df.iloc[0])-----------------')
print(df.iloc[0])
'''
x  z    1
   u    2
y  z    3
   u    4
Name: (a, c), dtype: int64
'''

交换索引

我们可以调用DataFrame对象的swaplevel方法来交换两个层级索引。该方法默认对倒数第2层与倒数第1层进行交换。我们也可以指定交换的层。层次从0开始,由外向内递增(或者由上到下递增),也可以指定负值,负值表示倒数第n层。除此之外,我们也可以使用层次索引的名称来进行交换。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019-06-13 13:07
# @Author  : LiYahui
# @Description : 
# 交换索引的层级,可以以一种不同的方式来进行展示(统计)。
import pandas as pd
data=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
df = pd.DataFrame(data, index=[["a", "a", "b", "b"],
            ["north", "north", "south", "south"], [2017, 2018, 2017, 2018]])
print(df)
'''
               0   1   2   3
a north 2017   1   2   3   4
        2018   5   6   7   8
b south 2017   9  10  11  12
        2018  13  14  15  16
'''
# 层级:从外层到内层,值为0, 1, 2……,同时,层级也可以为负值,表示倒数第n个层级(由内层到外层)。
# 例如,-1表示最内层。
# 如果没有显式指定交换的层级,则默认交换最内层的两个层级。
df = df.swaplevel(0, 2)
print(df)
'''
               0   1   2   3
2017 north a   1   2   3   4
2018 north a   5   6   7   8
2017 south b   9  10  11  12
2018 south b  13  14  15  16
'''
# 索引名字的作用。
# 除了数值来指定索引的层级外,我们也可以通过索引的名字来指定索引的层级。
df.index.names = ["x", "area", "year"]
df.swaplevel("area", "year")
print(df)
'''
                  0   1   2   3
x    area  year                
2017 north a      1   2   3   4
2018 north a      5   6   7   8
2017 south b      9  10  11  12
2018 south b     13  14  15  16
'''
df.sort_index()
print(df)
'''
                 0   1   2   3
x    area  year                
2017 north a      1   2   3   4
2018 north a      5   6   7   8
2017 south b      9  10  11  12
2018 south b     13  14  15  16
'''

索引排序

我们可以使用sort_index方法对索引进行排序处理。


# 层级索引的排序
df = pd.DataFrame(data, index=[["b", "a", "c", "c"],
            ["c", "y", "k", "k"], [3, -2, 5, 2]])
print(df)
'''
         0   1   2   3
b c  3   1   2   3   4
a y -2   5   6   7   8
c k  5   9  10  11  12
     2  13  14  15  16
'''
# 在对索引进行排序时,可以通过level参数指定索引的层级(排序的层级)。
# 如果没有显式指定,则默认为最外层的层级(层级为0)。
# 当我们对某个层级进行排序时,该层级的所有内层层级也会进行排序。
print(df.sort_index())
'''
         0   1   2   3
a y -2   5   6   7   8
b c  3   1   2   3   4
c k  2  13  14  15  16
     5   9  10  11  12
'''
print(df.sort_index(level=1))
'''
         0   1   2   3
b c  3   1   2   3   4
c k  2  13  14  15  16
     5   9  10  11  12
a y -2   5   6   7   8
'''

索引堆叠

取消堆叠

设置索引

重置索引


上一篇 下一篇

猜你喜欢

热点阅读