pandas(三)pandas层次化索引

pandas层次化索引

1. 创建多层行索引

In [1]:
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

1) 隐式构造

最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组

  • Series也可以创建多层索引
In [2]:
s = Series(data=[100,98,89,90],
           index=[["张三","张三","李四","李四"],["期中","期末","期中","期末"],
                  ["a","b","a","b"]])
s
Out[2]:
张三  期中  a    100
    期末  b     98
李四  期中  a     89
    期末  b     90
dtype: int64
In [3]:
df = DataFrame(data=[100,98,89,90],
           index=[["张三","张三","李四","李四"],["期中","期末","期中","期末"],
                  ["a","b","a","b"]],
           columns = ["python"]
              )
df
Out[3]:
   python
张三期中a100
期末b98
李四期中a89
期末b90
In [4]:
df1 = DataFrame(data=np.random.randint(0,150,size=(4,4)),
           index=[["张三","张三","李四","李四"],["期中","期末","期中","期末"],
                  ["a","b","a","b"]],
           columns = [["后台","后台","前端","前端"],
                      ["python","java","H5","jQuery"]]
              )
df1
Out[4]:
   后台前端
   pythonjavaH5jQuery
张三期中a41085528
期末b1411342782
李四期中a561448865
期末b291004367
In [5]:
df1.index
Out[5]:
MultiIndex(levels=[['张三', '李四'], ['期中', '期末'], ['a', 'b']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1], [0, 1, 0, 1]])

2) 显示构造pd.MultiIndex

  • 使用数组
In [6]:
# 创建一个多层索引
mindex =pd.MultiIndex.from_arrays([["a",'a','a','b','b','b'],
                     ['一单元',"二单元","三单元",'一单元',"二单元","三单元"]])
mindex
Out[6]:
MultiIndex(levels=[['a', 'b'], ['一单元', '三单元', '二单元']],
           labels=[[0, 0, 0, 1, 1, 1], [0, 2, 1, 0, 2, 1]])
In [7]:
# 用上面的多层索引创建一个df
df = DataFrame(np.random.randint(0,150,size=(6,1)),index=mindex,
               columns=["python"])
df
Out[7]:
  python
a一单元89
二单元9
三单元128
b一单元6
二单元62
三单元22
In [8]:
df = DataFrame(np.random.randint(0,150,size=(1,6)),index=["python"],
                  columns=mindex
              )
df
Out[8]:
 ab
 一单元二单元三单元一单元二单元三单元
python14114878049105
  • 使用tuple
In [9]:
mindex = pd.MultiIndex.from_tuples([("河南","郑州"),
                                    ("河南","洛阳"),
                                    ("山东","济南"),
                                    ("河北","石家庄"),
                                    ("北京","天安门"),
                                    ("四川","成都"),
                                    ("江苏","南京")]) 
# 注意:每个元组代表一个行(或列)的索引名,索引名要用元组的元素来体现
mindex
Out[9]:
MultiIndex(levels=[['北京', '四川', '山东', '江苏', '河北', '河南'], ['南京', '天安门', '成都', '洛阳', '济南', '石家庄', '郑州']],
           labels=[[5, 5, 2, 4, 0, 1, 3], [6, 3, 4, 5, 1, 2, 0]])
In [10]:
df = DataFrame(np.random.randint(1,100,size=(7,1)),index=mindex,
               columns=["收入(万)"])
df
Out[10]:
  收入(万)
河南郑州75
洛阳42
山东济南11
河北石家庄30
北京天安门34
四川成都1
江苏南京2
  • 使用product

    最简单,推荐使用

In [11]:
mindex = pd.MultiIndex.from_product([["河南","山东"],['郑州','济南']])
mindex
Out[11]:
MultiIndex(levels=[['山东', '河南'], ['济南', '郑州']],
           labels=[[1, 1, 0, 0], [1, 0, 1, 0]])
In [12]:
df = DataFrame(np.random.randint(0,100,size=(4,1)),index=mindex)
df
Out[12]:
  0
河南郑州98
济南84
山东郑州96
济南29
In [13]:
sindex = pd.MultiIndex.from_product([["张三","李四"],["期中","期末"],
                                     ["月考一","月考二","月考三"]])
sindex
Out[13]:
MultiIndex(levels=[['张三', '李四'], ['期中', '期末'], ['月考一', '月考三', '月考二']],
           labels=[[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1], [0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1]])
In [14]:
df = DataFrame(np.random.randint(0,150,size=(12,1)),index=sindex)
df
Out[14]:
   0
张三期中月考一66
月考二126
月考三132
期末月考一115
月考二58
月考三29
李四期中月考一10
月考二1
月考三65
期末月考一123
月考二106
月考三108

============================================

练习8:

  1. 创建一个DataFrame,表示出张三李四期中期末各科成绩

============================================

2. 多层列索引

除了行索引index,列索引columns也能用同样的方法创建多层索引

In [15]:
# 参照多层行索引
In [ ]:

3. 多层索引对象的索引与切片操作

1)Series的操作

【重要】对于Series来说,直接中括号[]与使用.loc()完全一样,因此,推荐使用中括号索引和切片。

(1) 索引

In [16]:
s
Out[16]:
张三  期中  a    100
    期末  b     98
李四  期中  a     89
    期末  b     90
dtype: int64
In [17]:
s["张三"]["期末"]["b"]
Out[17]:
98
In [18]:
s["张三","期中","a"]
Out[18]:
100
In [19]:
s[["张三","期中","afdsa","李四","李四"]] 
# 1、如果多个索引里面有无效,则不查找
# 2、如果有重复有效,只查找一次
Out[19]:
张三  期中  a    100
    期末  b     98
李四  期中  a     89
    期末  b     90
dtype: int64
In [ ]:

(2) 切片

In [20]:
s.loc["张三":"李四","期中":"期末"]
Out[20]:
张三  期中  a    100
    期末  b     98
李四  期中  a     89
    期末  b     90
dtype: int64
In [21]:
s.iloc[0:4]
# 【注意】多层索引创建的是显示索引,对隐式索引没有任何影响(隐式索引仍然是代表序列)
Out[21]:
张三  期中  a    100
    期末  b     98
李四  期中  a     89
    期末  b     90
dtype: int64

2)DataFrame的操作

(1) 可以直接使用列名称来进行列索引

(2) 使用行索引需要用ix(),loc()等函数

【极其重要】推荐使用loc()函数

注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!

In [22]:
sindex = pd.MultiIndex.from_product([["张三","李四"],["期中","期末"],
                                  ["月考一","月考二","月考三"]])
sindex
df = DataFrame(data=np.random.randint(0,150,size=(12,3)),index=sindex,
               columns=["python","java","UI"])
df
Out[22]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757
月考二743683
月考三1435450
李四期中月考一014053
月考二1475593
月考三12443137
期末月考一1392355
月考二1039951
月考三333
In [23]:
df["python"]["张三"]
Out[23]:
期中  月考一     13
    月考二      5
    月考三    109
期末  月考一    140
    月考二     74
    月考三    143
Name: python, dtype: int32
In [24]:
df[["python"]].loc["张三","期中"]
Out[24]:
 python
月考一13
月考二5
月考三109
In [25]:
df.loc["张三","期中",'月考一']
Out[25]:
python     13
java      148
UI         80
Name: (张三, 期中, 月考一), dtype: int32
In [26]:
df.loc[["张三","期中",'月考一',"李四"]]
Out[26]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757
月考二743683
月考三1435450
李四期中月考一014053
月考二1475593
月考三12443137
期末月考一1392355
月考二1039951
月考三333
In [27]:
df.loc["张三":"李四"]
Out[27]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757
月考二743683
月考三1435450
李四期中月考一014053
月考二1475593
月考三12443137
期末月考一1392355
月考二1039951
月考三333
In [28]:
df.iloc[0:4]
Out[28]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757

============================================

练习9:

  1. 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法

  2. 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?

============================================

In [ ]:

4. 索引的堆(stack)

  • stack()
  • unstack()
In [29]:
df
Out[29]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757
月考二743683
月考三1435450
李四期中月考一014053
月考二1475593
月考三12443137
期末月考一1392355
月考二1039951
月考三333
In [30]:
df1 = df.unstack(level=2)
df1
Out[30]:
  pythonjavaUI
  月考一月考三月考二月考一月考三月考二月考一月考三月考二
张三期中13109514870158012247
期末140143741375436575083
李四期中012414714043555313793
期末13931032339955351
In [31]:
df1.stack(level=1)
Out[31]:
   pythonjavaUI
张三期中月考一1314880
月考三10970122
月考二51547
期末月考一14013757
月考三1435450
月考二743683
李四期中月考一014053
月考三12443137
月考二1475593
期末月考一1392355
月考三333
月考二1039951

【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。

【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。

============================================

练习10:

  1. 使用unstack()将ddd变为两行,分别为期中期末

  2. 使用unstack()将ddd变为四行,分别为四个科目

============================================

5. 聚合操作

【注意】

  • 需要指定axis

  • 【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就保留。

所谓的聚合操作:平均数,方差,最大值,最小值……

In [32]:
df
Out[32]:
   pythonjavaUI
张三期中月考一1314880
月考二51547
月考三10970122
期末月考一14013757
月考二743683
月考三1435450
李四期中月考一014053
月考二1475593
月考三12443137
期末月考一1392355
月考二1039951
月考三333
In [33]:
df.div(10)
Out[33]:
   pythonjavaUI
张三期中月考一1.314.88.0
月考二0.51.54.7
月考三10.97.012.2
期末月考一14.013.75.7
月考二7.43.68.3
月考三14.35.45.0
李四期中月考一0.014.05.3
月考二14.75.59.3
月考三12.44.313.7
期末月考一13.92.35.5
月考二10.39.95.1
月考三0.30.30.3
In [34]:
df.divide(10,axis=1)
Out[34]:
   pythonjavaUI
张三期中月考一1.314.88.0
月考二0.51.54.7
月考三10.97.012.2
期末月考一14.013.75.7
月考二7.43.68.3
月考三14.35.45.0
李四期中月考一0.014.05.3
月考二14.75.59.3
月考三12.44.313.7
期末月考一13.92.35.5
月考二10.39.95.1
月考三0.30.30.3
In [35]:
df.sum(axis=1)
Out[35]:
张三  期中  月考一    241
        月考二     67
        月考三    301
    期末  月考一    334
        月考二    193
        月考三    247
李四  期中  月考一    193
        月考二    295
        月考三    304
    期末  月考一    217
        月考二    253
        月考三      9
dtype: int64
In [36]:
df.std(axis=0)
Out[36]:
python    61.193186
java      50.792731
UI        36.239419
dtype: float64
In [37]:
df.where(df>50,other=0) # 这个函数是根据条件来过滤
Out[37]:
   pythonjavaUI
张三期中月考一014880
月考二000
月考三10970122
期末月考一14013757
月考二74083
月考三143540
李四期中月考一014053
月考二1475593
月考三1240137
期末月考一139055
月考二1039951
月考三000

============================================

练习11:

  1. 计算各个科目期中期末平均成绩

  2. 计算各科目张三李四的最高分

============================================

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值