1. sci666首页
  2. 实用技巧
  3. 生物信息学

pandas中的index对象详解

在pandas中,Series和DataFrame对象是介绍的最多的,Index对象作为其构成的一部分,相关的介绍内容却比较少。对于Index对象而言,有以下两大类别
  1. Index

  2. MultiIndex

二者的区别就在于层级的多少,从字面含义也可以看出,MultiIndex指的是多层索引,Index是单层索引。

先从单层索引开始介绍,在声明数据框的时候,如果没有指定index和columns参数,pandas会自动生成对应的索引,示例如下

>>> 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对象,用法如下
>>> 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对象具有以下基本属性

>>> 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中,有以下几种方法,来显示创建数值索引

# 浮点数
>>> 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,用法如下

>>> 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有以下几个基本属性

>>> 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函数创建,基本用法如下

>>> 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具有以下基本属性

>>> 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函数生成,用法如下

 

>>> 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具有时间和日期对象的基本属性,示例如下

>>> 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类似,值为日期和时间的格式化结果,用法如下

>>> 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共享大部分属性,示例如下

>>> 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

将时间间隔转换为时间戳,用法如下

>>> 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具有以下基本属性

>>> 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. 从数组创建

用法如下

>>> 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. 从元组创建

用法如下

>>> 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. 从数据框创建

用法如下

>>> 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

该方法适用于元素的快速组合,用法如下

>>> 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的基本属性可以看出,它区别于单层索引的地方

>>> a = pd.MultiIndex.from_arrays(arrays, names=('index', 'group'))
>>> a.name
>>> a.names
FrozenList(['index', 'group'])
>>> a.nlevels
2
>>> a.levshape
(4, 2)

多层索引适用于多种分类标准的场景,极大增强了数据处理的灵活性。

这些可能会帮助到你: 问答社区 | 共享百度SVIP | 留言建议

欢迎入群交流:生信分析群: 732179952 · Meta分析群: 797345521 · 医学科研交流群: 797345521

发表评论

登录后才能评论