pandas(四)索引对象

一. 索引对象

在之前介绍的Series和DataFrame结构中,我们已经接触到了索引对象,它是pandas的重要组成部分。pandas定义了Index类来表示基本索引对象,想要获取数据的索引对象,只需调用数据的index属性即可index=df.index
这里有几点需要强调:

1. 索引是可以重复的

虽然很多时候都要求索引唯一,但这并不是强制的。我们可以使用索引对象is_unique属性,来判断索引是否唯一。

d=DF({'A':[1,2,3,4,5],'B':[6,7,8,9,10]},index=[1,1,2,2,3])
print(d)
print(d.index.is_unique)

Out[1]:
   A   B
1  1   6
1  2   7
2  3   8
2  4   9
3  5  10

False
2. 索引一旦确立就不可以再修改

索引是不可以修改的,但是可以全部重置。怎么理解呢?就是不可以修改索引的任何一部分,但是可以全部替换掉。索引的不可修改性十分重要,因为只有这样才能保证数据结构间安全共享(eg.自动对齐)。
那么如何替换掉所有的索引呢?有4种方法:

  • reset_index:替换旧索引,新的索引按0,1,2,3,4.....递增
    Series/DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=' ')
    level:要删除哪一级索引(多重索引)
    drop:False则将旧索引变成列,True则删除旧索引
    inplace:是否在原数据中修改
    col_level:如果列是多重标签,旧索引名插入到哪一层
    col_fill:如果列是多重标签,剩下的标签名是什么

  • set_index :将dataframe其中某列作为索引
    DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
    keys:要置为索引的列标签(列表)
    drop:True设置为新索引的列被删除,False被保留
    append:True保留原索引,keys中的列变为下一级索引
    inplace:是否在原数据中修改
    verify_integrity:True检测新的索引是否重复,重复则报错。

  • reindex:设置新索引, 新索引中不存在对应的数据,则将数据设为nan
    reindex更多的不是修改pandas对象的索引,而只是修改索引的顺序,如果修改的索引不存在就会使用默认的None代替此行。
    Series/Panel/DataFrame.reindex(labels=None, index=None, columns=None, axis=None, method=None, copy=True, level=None, fill_value=nan, limit=None, tolerance=None)
    前4个参数:传入新的索引数组,说明要修改行索引还是列标签。
    举个例子:我们看到,旧索引是[0,1,2,3,4],替换的新索引是[1,2,3,4,5,6],2个索引的交集被保留下来,新索引中不存在的标签0被删除,同时引入了新索引中的标签[5,6],数据为NAN

d=DF({'A':[1,1,3,4,5],'B':[6,7,8,9,10]})
print(d)
d=d.reindex([1,2,3,4,5,6])
print(d)

Out[2]:
   A   B
0  1   6
1  1   7
2  3   8
3  4   9
4  5  10
     A     B
1  1.0   7.0
2  3.0   8.0
3  4.0   9.0
4  5.0  10.0
5  NaN   NaN
6  NaN   NaN

method:新引入的索引标签的数据填充方法。pad / ffill向前保持一致;backfill / bfill向后保持一致;nearest和最近保持一致。

d=DF({'A':[1,1,3,4,5],'B':[6,7,8,9,10]},index=[0,1,3,4,5])
print(d)
d=d.reindex([1,2,3,4,5,6],method='pad')
print(d)

Out[3]:
   A   B
0  1   6
1  1   7
3  3   8
4  4   9
5  5  10
   A   B
1  1   7
2  1   7
3  3   8
4  4   9
5  5  10
6  5  10

fill_value:新引入的索引标签的数据填充值。

  • 直接赋值:直接将索引赋值给index变量,长度要和数据一致
data=pd.DataFrame({'A':[1,2,],'B':[0,0,],'C':[7,8]})
data.index=['a','b']

Out:
   A  B  C
a  1  0  7
b  2  0  8

二. 多重索引对象

多重索引(hierarchical indexing)是pandas的一个重要的功能,它可以在一个轴上有多个(两个以上)的索引,这就表示着,它能够以低维度形式来表示高维度的数据。注意,这里我说的是轴,这就意味着,多重索引可以是行索引,也可以是列索引。

1. 创建多重行索引
  1. 显式创建多重行索引:利用pandas.MultiIndex对象
    MultiIndex是pandas中标准的多重索引类,使用时只需将该对象赋值给基本结构的index参数即可。那么,我们如何创建这个MultiIndex对象呢?主要有以下几种方法:
  • 从数组构建:MultiIndex.from_arrays(arrays, sortorder=None, names=None)
  • 从元组构建:MultiIndex.from_tuples(tuples, sortorder=None, names=None)
  • 从数组交差配对构建:MultiIndex.from_product(iterables, sortorder=None, names=None)
    其中,第一个参数是索引结构,names是索引名,举个例子:
#注意观察从数组构建,与从交叉迭代构建的区别!!
arr=[['a','b'],[1,2]]
ind=pd.MultiIndex.from_arrays(arr,names=['alpha','number'])
data=pd.DataFrame({'A':[1,2,],'B':[0,0,],'C':[7,8]},index=ind)
print(data)

Out:
              A  B  C
alpha number         
a     1       1  0  7
b     2       2  0  8


arr=[['a','b'],[1,2]]
ind=pd.MultiIndex.from_product(arr,names=['alpha','number'])#交叉迭代
data=pd.DataFrame({'A':[1,2,3,4],'B':[0,0,5,6],'C':[7,8,0,0]},index=ind)
print(data)

Out:
              A  B  C
alpha number         
a     1       1  0  7
      2       2  0  8
b     1       3  5  0
      2       4  6  0
  1. 隐式创建多重行索引
  • 利用set_index()函数添加索引
    更多的时候我们不是自己创建数据结构,而是从文件中读取数据,然后自己设定索引列。还记得之前介绍set_index()函数的时候,提到过一个参数append,它被设置为True的时候,原索引不变,指定列被设置为原索引的下一级索引,我们可以利用这个特点,构造多重索引。
    举个例子:可以看到,栗子中的B列变成了2级索引。
data=pd.DataFrame({'A':[1,2,3],'B':[0,0,4],'C':[7,8,5]})
data.index.name='index'
data.set_index(keys=['B'],append=True,inplace=True)
print(data)

Out:
         A  C
index B      
0     0  1  7
1     0  2  8
2     4  3  5
  • 构造数据时,直接传入多个索引数组
    直接上栗子,这个很好理解
data=pd.DataFrame({'A':[1,2,3],'B':[0,0,4],'C':[7,8,5]},index=[['a','a','b'],[1,2,3]])
print(data)

Out:
     A  B  C
a 1  1  0  7
  2  2  0  8
b 3  3  4  5
2. 创建多重列索引

直接使用MultiIndex对象显示创建多重列索引。

arr=[['A','A','C'],['a','b','a']]
ind=pd.MultiIndex.from_arrays(arr,names=['letter','number'])
data=pd.DataFrame([[1,2,3],[0,0,4],[7,8,5]],columns=ind)
print(data)

Out:
letter  A     C
number  a  b  a
0       1  2  3
1       0  0  4
2       7  8  5
3.多重索引对象下的索引操作

之前讲pandas基本数据结构的时候,我们提到,常用的索引操作方式主要有以下几种:

  • 点字符 :访问列
  • 中括号 [ ]
  • loc[ ] :基于标签索引,可以批量选取
  • iloc[ ] :基于位置索引,可以批量选取
  • at[ ] : 基于标签索引,只能选取一个元素
  • iat[ ] : 基于位置索引,只能选取一个元素

在多重索引中也同样适用,而且使用方法基本雷同。这个时候可能会有人问,如何选择子索引呢?这个很简单,下面我们一起来看:
示例数据:

       A     C
       a  b  a
1 i    1  2  3
  ii   0  0  4
3 iii  7  8  5
  1. 索引元组:如果想要选取最外层索引,和普通单索引对象没区别。若是想要选取多层索引,就要使用元组的括号把索引包裹起来,我们看个栗子。
#只选最外层
print(data['A'])

Out:
       a  b
1 i    1  2
  ii   0  0
3 iii  7  8

#选列多层
print(data[ ('A','a') ])

Out:
1  i      1
   ii     0
3  iii    7

#行列都来个多层
print(data.loc[ (1,'ii') , ('A','a') ])

Out:
0

2.切片
多重索引也支持切片操作,只需用元组括号包裹多层的索引就可以了。

print(data.loc[(1,'ii'):,('A','a')])
Out:
1  ii     0
3  iii    7
另外,slice(None), 是Python中的切片操作,这里用来选择任意的id,要注意!不能使用‘:’来指定任意index,‘:’用来指定dataframe任意的列
print(data.loc[(slice(None),'ii')])
Out:
       A     C
       a  b  a
  ii   0  0  4

3.点字符
多重索引也支持点字符访问列,可以每一级使用一个点字符。

print(data.A.a)

Out:
1  i      1
   ii     0
3  iii    7
4.删除多重索引

使用pandas.MultiIndex.droplevel()函数,可以删除指定level的行索引。

data.index=data.index.droplevel(0)
print(data)

Out:
     A     C
     a  b  a
i    1  2  3
ii   0  0  4
iii  7  8  5
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容