欢迎关注”生信修炼手册”!
在pandas中,Series和DataFrame对象是介绍的最多的,Index对象作为其构成的一部分,相关的介绍内容却比较少。对于Index对象而言,有以下两大类别
- Index
- MultiIndex
二者的区别就在于层级的多少,从字面含义也可以看出,MultiIndex指的是多层索引,Index是单层索引。
先从单层索引开始介绍,在声明数据框的时候,如果没有指定index和columns参数,pandas会自动生成对应的索引,示例如下
代码语言:javascript复制>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame(np.random.rand(4, 4))
>>> df
0 1 2 3
0 0.776520 0.093637 0.819028 0.304640
1 0.130550 0.682061 0.102499 0.782682
2 0.995216 0.959426 0.337403 0.897070
3 0.253985 0.161841 0.536915 0.269828
>>> df.index
RangeIndex(start=0, stop=4, step=1)
>>> df.columns
RangeIndex(start=0, stop=4, step=1)
从运行结果可以看出,默认的行列标签皆为一个RangeIndex对象。RangeIndex属于Index中的一种形式,Index是更通用的函数,通过Index函数可以显示创建Index对象,用法如下
代码语言:javascript复制>>> df.index = pd.Index(list('ABCD'))
>>> df.columns = pd.Index(list('abcd'))
>>> df
a b c d
A 0.776520 0.093637 0.819028 0.304640
B 0.130550 0.682061 0.102499 0.782682
C 0.995216 0.959426 0.337403 0.897070
D 0.253985 0.161841 0.536915 0.269828
上述方法生成的Index对象就是一个单层索引了,Index对象具有以下基本属性
代码语言:javascript复制>>> a = pd.Index(list('ABCD'))
>>> a
Index(['A', 'B', 'C', 'D'], dtype='object')
# 值构成的数组
>>> a.array
<PandasArray>
['A', 'B', 'C', 'D']
Length: 4, dtype: object
# 数据类型
>>> a.dtype
dtype('O')
# level个数
>>> a.nlevels
1
# 维度
>>> a.ndim
1
# 尺寸
>>> a.shape
(4,)
# 个数
>>> a.size
4
# 值
>>> a.values
array(['A', 'B', 'C', 'D'], dtype=object)
除了常规的字符索引外,还有以下几种特定类型的索引
1. NumericIndex
数值索引,其值为数值,可以是整数,也可以是浮点数。在pandas中,有以下几种方法,来显示创建数值索引
代码语言:javascript复制# 浮点数
>>> pd.Float64Index([1, 2, 3, 4])
Float64Index([1.0, 2.0, 3.0, 4.0], dtype='float64')
# 整数
>>> pd.Int64Index([1, 2, 3, 4])
Int64Index([1, 2, 3, 4], dtype='int64')
# 无符号的整数
>>> pd.UInt64Index([1, 2, 3, 4])
UInt64Index([1, 2, 3, 4], dtype='uint64')
# 等差序列
>>> pd.RangeIndex(start=1,stop=8,step=2)
RangeIndex(start=1, stop=8, step=2)
2. CategoricalIndex
类似R语言中的因子,用于约束可选值的范围,超过范围的值强制变为NaN,用法如下
代码语言:javascript复制>>> df.index = pd.CategoricalIndex(list('ABCD'), categories=['A', 'B', 'C', 'D'])
>>> df
0 1 2 3
A 0.934708 0.642234 0.661185 0.240923
B 0.501524 0.137190 0.909126 0.561348
C 0.080566 0.399474 0.944330 0.774320
D 0.340798 0.723014 0.694030 0.101154
>>> df.index = pd.CategoricalIndex(list('ABCD'), categories=['A', 'B', 'C'])
>>> df
0 1 2 3
A 0.934708 0.642234 0.661185 0.240923
B 0.501524 0.137190 0.909126 0.561348
C 0.080566 0.399474 0.944330 0.774320
NaN 0.340798 0.723014 0.694030 0.101154
CategoricalIndex有以下几个基本属性
代码语言:javascript复制>>> a = pd.CategoricalIndex(list('ABCD'), categories=['A', 'B', 'C', 'D'])
>>> a.codes
array([0, 1, 2, 3], dtype=int8)
>>> a.categories
Index(['A', 'B', 'C', 'D'], dtype='object')
>>> a.ordered
False
3. IntervalIndex
索引的值为一个区间,通过interval_range函数创建,基本用法如下
代码语言:javascript复制>>> df.index = pd.interval_range(start=0, end=4)
>>> df
0 1 2 3
(0, 1] 0.934708 0.642234 0.661185 0.240923
(1, 2] 0.501524 0.137190 0.909126 0.561348
(2, 3] 0.080566 0.399474 0.944330 0.774320
(3, 4] 0.340798 0.723014 0.694030 0.101154
IntervalIndex具有以下基本属性
代码语言:javascript复制>>> a = pd.interval_range(start=0, end=4)
>>> a
IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4]],
closed='right',
dtype='interval[int64]')
# 区间左侧的值
>>> a.left
Int64Index([0, 1, 2, 3], dtype='int64')
# 区间右侧的值
>>> a.right
Int64Index([1, 2, 3, 4], dtype='int64')
# 区间的长度
>>> a.length
Int64Index([1, 1, 1, 1], dtype='int64')
# 区间的中心点
>>> a.mid
Float64Index([0.5, 1.5, 2.5, 3.5], dtype='float64')
4. DatetimeIndex
索引的值为日期和时间,可以通过date_range函数生成,用法如下
代码语言:javascript复制>>> df.index = pd.date_range('2020-01-01', periods=4, freq='D')
>>> df
0 1 2 3
2020-01-01 0.934708 0.642234 0.661185 0.240923
2020-01-02 0.501524 0.137190 0.909126 0.561348
2020-01-03 0.080566 0.399474 0.944330 0.774320
2020-01-04 0.340798 0.723014 0.694030 0.101154
DatetimeIndex具有时间和日期对象的基本属性,示例如下
代码语言:javascript复制>>> a = pd.date_range('2020-01-01', periods=4, freq='D')
>>> a.year
Int64Index([2020, 2020, 2020, 2020], dtype='int64')
>>> a.month
Int64Index([1, 1, 1, 1], dtype='int64')
>>> a.day
Int64Index([1, 2, 3, 4], dtype='int64')
>>> a.hour
Int64Index([0, 0, 0, 0], dtype='int64')
>>> a.minute
Int64Index([0, 0, 0, 0], dtype='int64')
>>> a.second
Int64Index([0, 0, 0, 0], dtype='int64')
5. PeriodIndex
和DatetimeIndex类似,值为日期和时间的格式化结果,用法如下
代码语言:javascript复制>>> df.index = pd.PeriodIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], freq = 'H')
>>> df
0 1 2 3
2020-01-01 00:00 0.934708 0.642234 0.661185 0.240923
2020-01-02 00:00 0.501524 0.137190 0.909126 0.561348
2020-01-03 00:00 0.080566 0.399474 0.944330 0.774320
2020-01-04 00:00 0.340798 0.723014 0.694030 0.101154
PeriodIndex和DatetimeIndex共享大部分属性,示例如下
代码语言:javascript复制>>> a = pd.PeriodIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], freq = 'H')
>>> a.day
Int64Index([1, 2, 3, 4], dtype='int64')
>>> a.month
Int64Index([1, 1, 1, 1], dtype='int64')
>>> a.year
Int64Index([2020, 2020, 2020, 2020], dtype='int64')
6. TimedeltaIndex
将时间间隔转换为时间戳,用法如下
代码语言:javascript复制>>> df.index = pd.TimedeltaIndex([12, 24, 36, 48], unit='h')
>>> df
0 1 2 3
0 days 12:00:00 0.934708 0.642234 0.661185 0.240923
1 days 00:00:00 0.501524 0.137190 0.909126 0.561348
1 days 12:00:00 0.080566 0.399474 0.944330 0.774320
2 days 00:00:00 0.340798 0.723014 0.694030 0.101154
TimedeltaIndex具有以下基本属性
代码语言:javascript复制>>> a.days
Int64Index([0, 1, 1, 2], dtype='int64')
>>> a.seconds
Int64Index([43200, 0, 43200, 0], dtype='int64')
>>> a.components
days hours minutes seconds milliseconds microseconds nanoseconds
0 0 12 0 0 0 0 0
1 1 0 0 0 0 0 0
2 1 12 0 0 0 0 0
3 2 0 0 0 0 0 0
当多个单层的索引结合在一起时,就形成了MultiIndex,具体的创建方式有以下几种
1. 从数组创建
用法如下
代码语言:javascript复制>>> arrays = [[1, 2, 3, 4], ['A', 'A', 'B', 'B']]
>>> pd.MultiIndex.from_arrays(arrays, names=('index', 'group'))
MultiIndex([(1, 'A'),
(2, 'A'),
(3, 'B'),
(4, 'B')],
names=['index', 'group'])
>>> df.index = pd.MultiIndex.from_arrays(arrays, names=('index', 'group'))
>>> df
0 1 2 3
index group
1 A 0.934708 0.642234 0.661185 0.240923
2 A 0.501524 0.137190 0.909126 0.561348
3 B 0.080566 0.399474 0.944330 0.774320
4 B 0.340798 0.723014 0.694030 0.101154
2. 从元组创建
用法如下
代码语言:javascript复制>>> pd.MultiIndex.from_tuples(([1, 'A'], [2, 'A'], [3, 'B'], [4, 'B']))
MultiIndex([(1, 'A'),
(2, 'A'),
(3, 'B'),
(4, 'B')],
)
>>> df.index = pd.MultiIndex.from_tuples(([1, 'A'], [2, 'A'], [3, 'B'], [4, 'B']))
>>> df
0 1 2 3
1 A 0.934708 0.642234 0.661185 0.240923
2 A 0.501524 0.137190 0.909126 0.561348
3 B 0.080566 0.399474 0.944330 0.774320
4 B 0.340798 0.723014 0.694030 0.101154
3. 从数据框创建
用法如下
代码语言:javascript复制>>> index = pd.DataFrame({'index':[1, 2, 3, 4], 'group':['A', 'A', 'B', 'B']})
>>> index
index group
0 1 A
1 2 A
2 3 B
3 4 B
>>> pd.MultiIndex.from_frame(index)
MultiIndex([(1, 'A'),
(2, 'A'),
(3, 'B'),
(4, 'B')],
names=['index', 'group'])
>>> df.index = pd.MultiIndex.from_frame(index)
>>> df
0 1 2 3
index group
1 A 0.934708 0.642234 0.661185 0.240923
2 A 0.501524 0.137190 0.909126 0.561348
3 B 0.080566 0.399474 0.944330 0.774320
4 B 0.340798 0.723014 0.694030 0.101154
4. from_product
该方法适用于元素的快速组合,用法如下
代码语言:javascript复制>>> pd.MultiIndex.from_product([[1,2],['A','B']])
MultiIndex([(1, 'A'),
(1, 'B'),
(2, 'A'),
(2, 'B')],
)
>>> df.index = pd.MultiIndex.from_product([[1,2],['A','B']])
>>> df
0 1 2 3
1 A 0.934708 0.642234 0.661185 0.240923
B 0.501524 0.137190 0.909126 0.561348
2 A 0.080566 0.399474 0.944330 0.774320
B 0.340798 0.723014 0.694030 0.101154
从MultiIndex的基本属性可以看出,它区别于单层索引的地方
代码语言:javascript复制>>> a = pd.MultiIndex.from_arrays(arrays, names=('index', 'group'))
>>> a.name
>>> a.names
FrozenList(['index', 'group'])
>>> a.nlevels
2
>>> a.levshape
(4, 2)
多层索引适用于多种分类标准的场景,极大增强了数据处理的灵活性。
·end·