索引类似元组,不能赋值修改。多层索引可以改变表的形态。
单层索引
>>> data = ['a', 'b', 'c']
# 创建索引,参数dtype指索引元素的类型默认为object
>>> index = pd.Index(data, name="name1")
# index.name index.values index.dtype
>>> index
Index(['a', 'b', 'c'], dtype='object', name='name1')
# access方式与ndarray或Series一样
index[0] # 单个
index[0:2] # 切片
index[[0, 2]] # 列表
index[[True,False,True]] # boolean值列表
# 改索引名
index.names = "new_name"
# 或者
index.set_names("new_name")
# 增加单个元素
index.insert(loc, value)
# 一次增加多个元素
index.append(Index)
# 删除单个元素。loc是数值
index.delete(loc)
# 删除多个元素。labels是index的内容
index.drop([labels])
# 求并集
index1.union(index2)
# 求交集
index1.intersection(index2)
多层索引
最外层的索引是可以直接使用的,比如[] (单个数字/数字段/单个label/llabel列表/布尔值列表)、.loc[]、iloc[]
level是从外到内(渐近数字的方向)递增的,0-based,实在不行可以用.index查一下,才好确定level的值。
# 创建索引
>>> data = [['a', 'one'], ['a', 'two'], ['b', 'one']]
>>> index = pd.MultiIndex.from_tuples(data, names=['name1', 'name2'])
>>> s = pd.Series([1,2,3], index=index)
# 这里索引值为空不是缺失,只是与前面的索引值一致才省略的
>>> s
name1 name2
a one 1
two 2
b one 3
dtype: int64
# access与单层索引完全一致
>>> index[0]
('a', 'one')
# 获取某一层的索引
>>> index.get_level_values(0)
Index(['a', 'a', 'b'], dtype='object', name='name1')
>>> index.get_level_values(1)
Index(['one', 'two', 'one'], dtype='object', name='name2')
# 改索引名。多层索引要设level或者names给列表
MultiIndex.set_names(names, level=None, inplace=False)
# 索引次序交换:改变level i 和level j 的次序。
MultiIndex.swaplevel(i=-2, j=-1)
# 同理还有:但是这里的Series和DataFrame必须具有多层索引,才能这样交换。单层的Index会报错的。
Series.swaplevel(i=-2, j=-1)
# DataFrame交换时,axis=0是行索引,1是列索引
DataFrame.swaplevel(i=-2, j=-1, axis = 1)
内层索引不能直接引用,必须先外层、再内层,且只能使用单索引。
>>> columns = index.copy()
>>> columns.set_names( names = ['name3','name4'], level = [0,1], inplace = True) #列索引取和行索引相同,只是改了名字
>>> df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], index= index, columns = columns)
>>> df
name3 a b
name4 one two one
name1 name2
a one 1 2 3
two 4 5 6
b one 7 8 9
# [,]是按列,先取外层columns,再取内层columns
>>> df['a','two']
name1 name2
a one 2
two 5
b one 8
Name: (a, two), dtype: int64
# .loc[,]是按行,先去外层index,再取内层index
>>> df.loc['a', 'two']
name3 name4
a one 4
two 5
b one 6
Name: (a, two), dtype: int64
# .iloc[,]只用数字索引,所以无视索引
# xs 方法只能在单层选取,不能行和列同时操作
Series.xs(key, level=None, drop_level=True)
DataFrame.xs(key, axis=0, level=None, drop_level=True)
# axis=0是行索引,axis=1是列索引
# drop_level默认不显示用于选取level的索引
普通列转化为index
DataFrame中的列
DataFrame.set_index(keys, drop=True, append=False, inplace=False)
- keys:单个列名则变成单层索引,列名列表则变为多重索引
- drop:True会丢掉原本的列,完全变成索引
- append:False的话,不保留原来的索引,新索引直接替换掉旧索引
- inplace:是否原地修改
>>> data = [[1,2,3],[4,5,6]]
>>> index = ['a','b']
>>> columns = ['A','B','C']
>>> df = pd.DataFrame( data = data, index = index, columns = columns)
>>> df
A B C
a 1 2 3
b 4 5 6
# 这样是保留了原来的索引ab,也保留了原本的值。
>>> df.set_index(['A','C'], drop = False, append = True)
A B C
A C
a 1 3 1 2 3
b 4 6 4 5 6
任意列
仍然用set_index,但是注意,keys=[列表或Series列表]。
# 注意这里keys=[我是列表]
>>> li = ['c', 'd']
>>> df.set_index(keys=[li])
A B C
c 1 2 3
d 4 5 6
# 建立多层索引可以用[Series]
>>> s1 = pd.Series(['e','f'])
>>> df2 = df.set_index([s1,s1])
>>> df2
A B C
e e 1 2 3
f f 4 5 6
index转化为普通列
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=’’)
- level:数值/index的名字,可以为列表,默认包含所有的index
- drop:默认将index插入列中。True的话,不插入,直接丢弃。
- col_level:如果列索引是多重的,那么新插入的列设置哪一层索引?
- col_fill:如果有多层索引,除了col_level已经设置的,其他设置为什么?
>>> df
A B C
a 1 2 3
b 4 5 6
>>> df1 = df.set_index(['A','C'], drop = True, append = True)
>>> df1
B
A C
a 1 3 2
b 4 6 5
# 由此可知,level=0是a, b ; level=1是'A'列
>>> df1.index
MultiIndex([('a', 1, 3),
('b', 4, 6)],
names=[None, 'A', 'C'])
# 默认情况下,所有index列都被恢复了。
>>> df1.reset_index()
level_0 A C B
0 a 1 3 2
1 b 4 6 5
如果一列index没有名字,那么变为普通列后,最外层 columns(其实是level=0的columns)就叫index,否则叫原来的名字。内层根据col_fill值来。