Pandas教程(四)—— 分层索引及数据联合
1.分层索引
分层索引就是在一个轴上拥有多个(两个及以上)索引级别,能以低维度形式处理高维度数据。
?1.1?分层索引的创建
? ?1.1.1 方式一:直接设置
- 1)在创建series、dataframe或读取文件时时,行名或列名输入一个二维的列表;
- 2)使用语句:data.set_index( )? ? 括号中输入一个含多个列名的列表
? ? ?set_index会生成一个新的dataframe,使用一个或多个列作为索引
? ? ?reset_index是它的反函数,分层索引中的索引层级会被移动到列中
import pandas as pd
data = {"城市":["北京","上海","深圳","广州"],
"同比":[120.7,127.3,119.4,140.9],
"环比":[101.5,101.2,101.3,120.0],
"定基":[121.4,127.8,120.0,145.5]}
# 法一
data1 = pd.DataFrame(data,
index = [["A","A","B","B"],[1,2,1,4]], #第一层中相同的要放在一起
columns =["城市","同比","环比","定基"])
# 法二
data2 = pd.DataFrame(data,columns =["城市","同比","环比","定基"])
data2 = data2.set_index(['城市','同比'])
输出结果如下:
我们得到的就是一个以 MutiIndex 对象?作为索引的 美化视图
print(data.index) #打印dataframe的索引
返回结果如下:?
? ?1.1.2 利用方法属性创建?
- 以下方法只是创建出多维索引 Mutiindex 对象,还需要在定义时将其赋给Dataframe
? ? ? ?创建语法:pd.?MutiIndex.下述方法()
方法 | 描述 |
---|---|
from_arrays | 接收一个多维数组,高维指定高层索引,低维指定底层索引 |
from_tuples | 接收一个元组的列表,每个元组指定每个对应索引 (高维索引,低维索引)? ? 如上图 |
from_product | 接收一个可迭代对象的列表,使用笛卡尔积的方式创建 |
- 补充:笛卡尔积
两个集合X和Y的笛卡尔积(X ×?Y)是指? 第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员
例如:A={a, b},B={0, 1, 2},则笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
import pandas as pd
# 利用数组设置
mult1 = pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]],names = ["x","y"])
print(mult1)
# 利用元组设置
mult2 = pd.MultiIndex.from_tuples([('a', 1),('a', 2),('b', 1),('b', 2)],names = ["x","y"])
print(mult2)
# 推荐:利用可迭代对象设置
mult3 = pd.MultiIndex.from_product([[2019,2020],[1,2]])
mult3.names = ["年","月"] # 也可以这样设置索引名
print(mult3)
# 将mutiindex赋给数据
mult4 = pd.MultiIndex.from_product([["山东","北京"],["土豆","茄子"]],names=['城市', '蔬菜'])
data = pd.DataFrame(np.random.random(size=(4,4)),
index = mult3,
columns = mult4)
print(data)
?1.2 分层索引的切片或索引
? ? 首先我们先创建一个多层索引的dataframe,并以此为例讲解
(参考了该文章:https://blog.csdn.net/qq_35318838/article/details/102469320)
import pandas as pd
mult3 = pd.MultiIndex.from_product([[2019,2020],[1,2]])
mult3.names = ["年","月"]
mult4 = pd.MultiIndex.from_product([["山东","北京"],["土豆","茄子"]],names=['城市', '蔬菜'])
data = pd.DataFrame(np.random.random(size=(4,4)),index = mult3,columns = mult4)
print(data)
? ? 1.2.1 对列标签层次化索引
- 最外层列标签的索引:data? [ "外层列名"?]?
- 内层列标签的索引:? ?data [ "外层标签","内层标签"?]
print(data["山东"]) # 索引山东列
print("-"*50)
print(data["山东","土豆"]) #索引山东的土豆列
? ? 1.2.2?对行标签层次化索引
- 最外层行标签的索引:data.loc? [ "外层行名"?]?
- 内层行标签的索引:? ?data.loc [ "外层标签","内层标签"?]
print(data.loc[2019]) # 索引2019年 行
print("-"*50)
print(data.loc[2019,1]) # 索引2019一月 行
? ? 1.2.3?使用xs进行索引
? ? ? pandas 中的?xs 方法在索引时可以直接指定层次化索引中元素和层级?
- 语法:data.xs( x ,? level=, axis=1)
参数说明:
? ? ? ? ? x:标签或标签的元组
? ? ? ? ? level:层级名(本例中行索引层级包括:蔬菜、城市? ?? ? ? ?列索引层级包括:年、月)
? ? ? ? ? axis:哪个轴向上的层级
print(data.xs(1,level="月",axis=0)) # 列切片 月层级上所有1月
print("-"*50)
print(data.xs("土豆",level="蔬菜",axis=1)) # 行切片 蔬菜层级上所有土豆
? ? 1.2.4 使用loc和slice方法切片
? ? 在列索引中,“ :”代表选取全部列,但冒号不能在行索引中使用;
? ? 行索引中应该使用slice(None)代表选取所有行
print(data.loc[(slice(None),1),:]) # 选取所有1月
print(data.loc[slice(None),(slice(None),"茄子")]) # 选取所有的茄子
?1.3 重排序和层级排序
方法 | 描述 |
---|---|
data.swaplevel(“key1”,“key2”) | 传入两个层级序号或层级名称,互换这两个层级的位置 |
data.sort_index(level =) | 传入一个层级,使结果按照层级进行字典排序 |
2.联合与合并数据集
- 基础知识:四种连接方式
? ? ? ? 内连接(inner)、左连接(left)、右连接(right)、全外连接(outer? 全部都要)
?2.1 Merge函数
? ?merge函数有点类似sql中的join,主要用于将两个Dataframe根据一些共有的列连接起来
- 语法: pd.merge(data1,data2,参数)?
常用参数:
? ? ? ? ?
? ? ? ? ? ?how:?数据连接的方式:inner(默认)、left、right、outer(即上面四种)
? ? ? ? ? ?on:? ??用来连接的列名,必须是在两边的df中都有的列名;若使用多个键进行合并,
? ? ? ? ? ? ? ? ? ? ? ?传入一个含多个列名的列表,把多个键看作一个元组数据当作单个键处理即可
? ? ? ? ? ?
? ? ? ? ? ?suffixes:对于左右表中的重名列,添加后缀进行区分,默认为("_x","_y")
? ? ? ? ? ?left_on / right_on:? 左(右)表中用作连接键的列名
? ? ? ? ? ?left_index / right_index: 将左(右)表的行索引index用作连接键,布尔值 默认F? ??
?? 2.1.1 根据单个连接键合并
- pd.merge(数据1,数据2,on='姓名',how='inner')
import pandas as pd
数据1= pd.DataFrame({'姓名':['叶问','李小龙','孙兴华','李小龙','叶问','叶问'],'出手次数1':np.arange(6)})
数据2 = pd.DataFrame({'姓名':['黄飞鸿','孙兴华','李小龙'],'出手次数2':[1,2,3]})
数据3 = pd.merge(数据1,数据2,on='姓名',how='inner')
print(数据3)
? ?2.1.2 根据多个连接键合并
- 根据多个键进行合并时,on参数需传入一个含多个列名的列表,把多个键看作一个元组数据当作单个键处理即可
import pandas as pd
数据1 = pd.DataFrame({'姓名': ['张三', '张三', '王五'],'班级': ['1班', '2班', '1班'],'分数': [10,20,30]})
数据2 = pd.DataFrame({'姓名': ['张三', '张三', '王五','王五'],'班级': ['1班', '1班', '1班','2班'],'分数': [40,50,60,70]})
数据3 = pd.merge(数据1,数据2,on=['姓名','班级'],how='outer',suffixes=('_left','_right')) # 外连接(并集)的结果
print(数据3)
? ?2.1.3 索引作为键进行合并
- 如果我们希望以df的索引作为合并的键,只需传递参数?left_index / right_index = True 即可
import pandas as pd
import numpy as np
data1 = pd.DataFrame({"key1":["Ohio","Ohio","Ohio","Nevada","Nevada"],
"key2":[2000,2001,2002,2001,2002],
"data":np.arange(5)})
data2 = pd.DataFrame(np.arange(12).reshape(6,2),
index = [["Nevada","Nevada","Ohio","Ohio","Ohio","Ohio"],
[2001,2000,2000,2000,2001,2002]],
columns = ["first","second"])
data3 = pd.merge(data1,data2,left_on=["key1","key2"],right_index=True,how="outer")
print(data3)
?2.2 join函数
? ? ? join函数可以便捷的进行横向连接,它默认以索引为连接键,且默认左连接
- 语法:left_data?. join(right_data,on = None,how = 'left')?
- 若要一次组合多个dataframe,只需传入一个列表即可。例如:result = left.join([right, right2])?
import pandas as pd
left = pd.DataFrame({'姓名1':['叶问','李小龙','孙兴华'],'年龄1':[127,80,20]})
right = pd.DataFrame({'姓名2':['大刀王五','霍元甲','陈真'],'年龄2':[176,152,128]})
print(left.join(right))
?2.3 concat函数
? ? ? ?contact函数主要负责数据组合中的拼接、绑定或堆叠,也可以总结为沿轴向对数据进行连接
- 语法:contact([ data1,data2...?],axis = ,join = ,keys = ...)
?常用参数:
?
? ? ? ? ? ? ? ? ?axis?:沿哪个轴进行数据连接,默认为0,纵向连接
? ? ? ? ? ? ? ? ?join?:选择连接方式,inner(默认)或outer
? ? ? ? ? ? ? ? ?join_axes :可以指定根据那个轴来对齐数据,代替join的作用
? ? ? ? ? ? ? ? ?ignore_index:是否忽略原索引,产生一段新的索引(默认False,不忽略)
? ? ? ? ? ? ? ? ?keys:输入一个列表,增加一个区分数据组的键,形成分层索引
?
? ? 2.3.1 纵向拼接 /?分层索引
? ? ? contact函数默认(axis = 0)就是纵向拼接,即首尾相连
? ? ? 此时我们可以通过 添加一个keys或传入字典 来区分拼接后的数据到底来自哪个表
- 语法1:contact([ df1,df2,df3 ],axis = 0,keys=['x', 'y', 'z'])?
- 语法2:contact( {?'x': df1,? 'y': df2,? 'z': df3 },axis = 0)
?
? ? 2.3.2 横向拼接 / 指定拼接键
? ? ? 当axis = 1的时候,concat就是行对齐,即横向合并
? ? ? 我们也可以通过传入join_axes,来指定根据那个轴来对齐数据
- 语法:pd.concat ( [ df1, df4 ] , axis = 1 ,? join_axes = [df1.index] )
? ? 2.3.3 无视原来的index
? ? ? ? 如果两个表的index都没有实际含义,或拼接后变得混乱,我们可以传入?ignore_index 参数来生成一个新的index?
- 语法:?pd.concat ( [ df1, df4 ] , axis = 1 ,?ignore_index = True)
?
?2.4 联合重叠的数据?
? ? ? 在数据操作中,我们经常需要去联合一些重叠的数据,进而去填补一些缺失值
?
- 方法一:np.where(condition,x,y) 等价于 x if condition else y
? ? ? ?语法:np.where(pd.isnull(data1),data2,data1)?
该语法相当于先判断data1中的数据是否为空值,如果为空就用data2的数据,如果不为空,就用data1的数据?
- 方法二:combine_first
? ? ? ?语法:data1.combine_first(data2)
改语法是逐列对df做相同的操作,可以认为是根据data2 来修补 data1的缺失值
?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!