文章目录


数据分析.pandas.索引及复合索引

一、索引(index)

pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,被作为索引的数组会被转换成一个Index:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(12).reshape((3,4)),index=(list("abc")),columns=(list("ABCD")))
print(df)
# A B C D
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11

print(df.index)
# Index(['a', 'b', 'c'], dtype='object')

除了类似于数组,Index也具有set集合的功能:

In [85]: frame3
Out[85]:
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

In [86]: frame3.columns
Out[86]: Index(['Nevada', 'Ohio'], dtype='object', name='state')

In [87]: 'Ohio' in frame3.columns
Out[87]: True

In [88]: 2003 in frame3.index
Out[88]: False

与python的集合不同,pandas的Index可以包含重复的标签,选择重复的标签,会显示所有的结果。

In [89]: dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar'])
In [90]: dup_labels
Out[90]: Index(['foo', 'foo', 'bar', 'bar'], dtype='object')

下面是Index对象主要的方法和属性:

【Python】数据分析.pandas.索引、重建索引、复合索引_数据分析


返回顶部


二、重建索引(reindex)

pandas对象的reindex方法作用是重建新的索引。
method选项可填入的参数包括 : {None, ‘backfill’/‘bfill’, ‘pad’/‘ffill’, ‘nearest’}
默认为None: 不进行填充
pad/ffill: 前向填充,使用前面的有效值进行填充
backfill/bfill: 后向填充,使用后面有效值进行填充
nearest: 使用最近的有效值进行填充

【Python】数据分析.pandas.索引、重建索引、复合索引_数据分析_02

In [95]: obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
In [96]: obj3
Out[96]:
0 blue
2 purple
4 yellow
dtype: object

In [97]: obj3.reindex(range(6), method='ffill')
Out[97]:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object

列可以用columns关键字重新索引:

df = pd.DataFrame(np.arange(12).reshape((3,4)),
index=(list("abc")),columns=(list("ABCD")))
print(df)
# A B C D
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11

print(df.index)
# Index(['a', 'b', 'c'], dtype='object')

借助DataFrame,reindex可以修改(行)索引和列。只传递一个序列时,会重新索引结果的行:

df = pd.DataFrame(np.arange(12).reshape((3,4)),
index=(list("abc")),columns=(list("ABCD")))
print(df)
# A B C D
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11

print(df.index)
# Index(['a', 'b', 'c'], dtype='object')

df3 = df.reindex(list("abcd"))
print(df3)
# A B C D
# a 0.0 1.0 2.0 3.0
# b 4.0 5.0 6.0 7.0
# c 8.0 9.0 10.0 11.0
# d NaN NaN NaN NaN

返回顶部


三、复合索引

索引可以包含一个、两个或多个列。两个或更多个列上的索引被称作复合索引。

pandas中set_index方法是专门用来将某一列设置为index的方法。它具有简单,方便,快捷的特点。
主要参数:
keys
需要设置为index的列名
drop
True or False。在将原来的列设置为index,是否需要删除原来的列。默认为True,即删除(Delete columns to be used as the new index.)
append
True or False。新的index设置之后,是否要删除原来的index。 默认为True。(Whether to append columns to existing index.)
inplace
True or False。是否要用新的DataFrame取代原来的DataFrame。默认False,即不取代。**( Modify the DataFrame in place (do not create a new object))

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(12).reshape((3,4)),
index=(list("abc")),columns=(list("ABCD")))
print(df)
# A B C D
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11

print(df.index)
# Index(['a', 'b', 'c'], dtype='object')

#指定索引
df.index = ["a","b","m"]
print(df)
# A B C D
# a 0 1 2 3
# b 4 5 6 7
# m 8 9 10 11

#重新设置索引
print(df.reindex(list("abd")))
# A B C D
# a 0.0 1.0 2.0 3.0
# b 4.0 5.0 6.0 7.0
# d NaN NaN NaN NaN

#指定某一列为索引
print(df.set_index("A"))
# B C D
# A
# 0 1 2 3
# 4 5 6 7
# 8 9 10 11
print(df.set_index("A",drop=False))
# A B C D
# A
# 0 0 1 2 3
# 4 4 5 6 7

#设置两个索引
df1 = df.set_index(["A","B"],drop=False)
print(df1)
# A B C D
# A B
# 0 1 0 1 2 3
# 4 5 4 5 6 7
# 8 9 8 9 10 11
print(df1.index)
# MultiIndex([(0, 1),
# (4, 5),
# (8, 9)],
# names=['A', 'B'])

#设置三个索引
df2 = df.set_index(["A","B","C"],drop=False)
print(df2)
# A B C D
# A B C
# 0 1 2 0 1 2 3
# 4 5 6 4 5 6 7
# 8 9 10 8 9 10 11
print(df2.index)
# MultiIndex([(0, 1, 2),
# (4, 5, 6),
# (8, 9, 10)],
# names=['A', 'B', 'C'])

返回顶部


四、Series、DataFrame复合索引的操作

a = pd.DataFrame({'a':range(7),'b':range(7,0,-1),'c':['one','one','one','two','two','two','two'],'d':list("hjklmno")})
print(a)
# a b c d
# 0 0 7 one h
# 1 1 6 one j
# 2 2 5 one k
# 3 3 4 two l
# 4 4 3 two m
# 5 5 2 two n
# 6 6 1 two o
b = a.set_index(["c","d"]) #复合索引
print(b)
# a b
# c d
# one h 0 7
# j 1 6
# k 2 5
# two l 3 4
# m 4 3
# n 5 2
# o 6 1

print(b.loc["one"].loc["h"]) #切片取值
# a 0
# b 7

上面我们提过,pandas的Index可以包含重复的标签,选择重复的标签,会显示所有的结果,如上面案例所示,在设置dataframe表时,我们设置c列包含有重复的值,当我们设置c、d列为索引时,自动去重,并在对应d列首个内层索引处显示出外层唯一索引。

#对于复合索引Series的切片操作
print(c["one"]["j"]) #1
print(c["one"])
# h 0
# j 1
# k 2
# Name: a, dtype: int64

#我们将c、d两列的顺序调换
d = a.set_index(["d","c"])["a"]
print(d)
# a
# d c
# h one 0
# j one 1
# k one 2
# l two 3
# m two 4
# n two 5
# o two 6

#此时若要取内层索引为one的数据
#法一:以c["..."]的形式,将内层索引为one的一个一个取出
#法二:使用swaplevel()方法交换
e = d.swaplevel()
print(e)
# c d
# one h 0
# j 1
# k 2
# two l 3
# m 4
# n 5
# o 6
print(e["one"])
# d
# h 0
# j 1
# k 2
# Name: a, dtype: int64
print(e["one","h"])
# 0

返回顶部