Pandas索引操作

Pandas中的索引操作非常灵活,功能非常强大。学会他的索引操作能帮助我们更好的处理数据。下面来对索引进行讲解。

一、索引类型:

不管是 Series还是 DataFrame,索引对象的类型都是 Index或者其子类。我们可以通过以下代码查看:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(4,4))

print(type(df.index))
print(type(df.columns))

输出结果为:

RangeIndex(start=0, stop=4, step=1)
RangeIndex(start=0, stop=4, step=1)

可以看到行和列的类型,都是 RangeIndex类型。 RangeIndex属于 Index的子类。当然我们也可以直接通过显示创建 Index的方式,修改 dfindexcolumns,示例代码如下:

输出结果为:

abcdA0.2749630.0844070.1578350.797312B0.0908300.5122630.4193730.466661C0.9030840.3676360.2197190.258690D0.0092050.6316680.4954820.316959

常用的 Index类型还有以下。

区间索引,用法与Python中的 range函数类似,可以指定 startstopstep参数。示例代码如下:

df.index = pd.RangeIndex(start=1, stop=9, step=2)

数值类型的索引,包括有浮点类型的 Float64Index、整形的 Int64Index、无符号整形的 UInt64Index、序列类型的 RangeIndex。他们的用法如下:

浮点类型
>>> 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")

其中 Float64IndexInt64IndexUInt64IndexPandas 2.0版本中会被移除,统一使用 NumericIndex代替。

分类索引,索引的值只能是指定分类的。否则会用NAN来代替。示例代码如下:

>>> df.index = pd.CategoricalIndex(list("ABCD"),categories=list("ABCD"))

输出结果为:

    a        b        c        d
A    0.274963    0.084407    0.157835    0.797312
B    0.090830    0.512263    0.419373    0.466661
C    0.903084    0.367636    0.219719    0.258690
D    0.009205    0.631668    0.495482    0.316959

如果将索引值修改为 list("ABCE"),因为 E不在 categories参数指定的范围内,因此会用NAN来代替。

df.index = pd.CategoricalIndex(list("ABCE"),categories=list("ABCD"))

输出结果为:

    a        b        c        d
A    0.274963    0.084407    0.157835    0.797312
B    0.090830    0.512263    0.419373    0.466661
C    0.903084    0.367636    0.219719    0.258690
NaN    0.009205    0.631668    0.495482    0.316959

关于 CategoricalIndex的更多用法请参考官方文档:https://pandas.pydata.org/docs/reference/api/pandas.CategoricalIndex.html

间隔索引,索引的值为一个区间,可以通过 pd.interval_range函数创建。示例代码如下:

df.index = pd.interval_range(start=0, end=4)

输出结果为:

    a        b        c        d
(0, 1]    0.274963    0.084407    0.157835    0.797312
(1, 2]    0.090830    0.512263    0.419373    0.466661
(2, 3]    0.903084    0.367636    0.219719    0.258690
(3, 4]    0.009205    0.631668    0.495482    0.316959

interval_range函数的 startend参数,也可以为 datetime类型,并且还可以通过 periods参数指定区间的个数。示例代码如下:

from datetime import datetime
pd.interval_range(start=datetime(year=2022, month=1, day=1), end=datetime(year=2022, month=1, day=31), periods=4)

输出结果如下:

IntervalIndex([(2022-01-01, 2022-01-11], (2022-01-11, 2022-01-21], (2022-01-21, 2022-01-31]],
              closed='right',
              dtype='interval[datetime64[ns]]')

关于更多 interval_rangeIntervalIndex的用法,请参考官方文档:

日期时间索引,可以通过 pd.date_range函数创建。示例代码如下:

df.index = pd.date_range("2022-01-01", periods=4, freq="Y")

输出结果为:

        a            b            c            d
2022-12-31    0.274963    0.084407    0.157835    0.797312
2023-12-31    0.090830    0.512263    0.419373    0.466661
2024-12-31    0.903084    0.367636    0.219719    0.258690
2025-12-31    0.009205    0.631668    0.495482    0.316959

其中 freq参数默认是 D,也就是天,也可以选择日,时分秒等。以下链接可以查看所有的选择:https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases

关于 date_rangeDatetimeIndex的更多用法请参考官方文档:

时间间隔索引。可以通过 pd.TimedeltaIndex创建。示例代码如下:

df.index = pd.TimedeltaIndex([12,24,36,48], unit="m")

输出结果为:

        a            b            c            d
0 days 00:12:00    0.274963    0.084407    0.157835    0.797312
0 days 00:24:00    0.090830    0.512263    0.419373    0.466661
0 days 00:36:00    0.903084    0.367636    0.219719    0.258690
0 days 00:48:00    0.009205    0.631668    0.495482    0.316959

以上便是常用的索引类型。索引类型有一个特点, 一旦索引被创建后,将无法进行修改。 示例代码如下:

df.index[0] = 2

执行上述代码,将会抛出类似以下的错误信息:

TypeError: Index does not support mutable operations

关于 TimedeltaIndex的更多用法请参考官方文档:https://pandas.pydata.org/docs/reference/api/pandas.TimedeltaIndex.html

二、Series索引:

在创建 Series对象的时候,默认的索引值是0-N,我们也可以通过 index参数单独设置。示例代码如下:

series = pd.Series(range(5), index = ['a', 'b', 'c', 'd', 'e'])
print(series.head())

输出结果为:

a    0
b    1
c    2
d    3
e    4
dtype: int64

因为在 Series中,只有一列,因此不存在列索引。行索引可以通过索引名称获取,也可以通过索引下标获取。示例代码如下:

series = pd.Series(range(0, 10, 2), index = ['a', 'b', 'c', 'd', 'e'])
print(series)
print(series['a'])
print(series[1])

输出结果为:

a    0
b    2
c    4
d    6
e    8
dtype: int64
0
2

如果索引是时间类型,则通过时间字符串即可获取到。示例代码如下:

series = pd.Series(range(2, 12, 2))
series.index = pd.date_range("2022-01-01", periods=5, freq="H")
print(series)
print(series["2022-01-01 00:00:00"])

输出结果如下:

2022-01-01 00:00:00     2
2022-01-01 01:00:00     4
2022-01-01 02:00:00     6
2022-01-01 03:00:00     8
2022-01-01 04:00:00    10
Freq: H, dtype: int64
2

索引也可以类似使用列表的切片方式来提取。切片可以是索引名称,也可以是序号。示例代码如下:

import pandas as pd

persons = ['张三','李四','王五']
series = pd.Series(persons, index=list("ABC"))

根据索引名切片
print(series["A":"B"])
根据索引序号切片
print(series[0:2])

以上两个输出结果都为:

A    张三
B    李四
dtype: object

可以注意到,如果用索引名称进行切片,那么会包含终止索引的。

之前通过切片可以一次性获取多个索引的值,也可以直接指定具体几个位置的索引。示例代码如下:

import pandas as pd

persons = ['张三','李四','王五','赵六']
series = pd.Series(persons, index=list("ABCD"))

获取索引下标为0和2的元素
print(series[[0,2]])
获取索引名称为A和C的元素
print(series[["A","C"]])

以上两个print语句的代码执行结果如下:

A    张三
C    王五
dtype: object

布尔索引,就是提供条件,选择满足条件的值出来。示例代码如下:

import pandas as pd

persons = [18,20,39,45]
series = pd.Series(persons, index=['张三','李四','王五','赵六'])

选择值大于20的所有元素
print(series[series>20])

输出结果如下:

王五    39
赵六    45
dtype: int64

三、DataFrame索引:

创建 DataFrame的时候,可以指定行索引和列索引,示例代码如下:

import numpy as np

df = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'], index=["11","22","33","44","55"])
print(df)

输出结果如下:

           a         b         c         d
11  0.963458  1.896413  0.042990 -0.582146
22 -1.764354 -1.529342 -0.430965 -0.215617
33  0.356744 -0.729001 -0.543932  0.852026
44  0.488031  0.459878 -0.577119  0.961865
55 -0.808639  0.925949 -1.333124  0.526995

下面我们将使用以上的 df对象进行讲解。

DataFrame中包含列索引,可以通过以下方式来获取列索引的数据:

只获取一列,返回series类型
print(df["a"])
获取多列,返回DataFrame类型
print(df[["a", "b"]])

Series通过 []来获取行索引,而 DataFrame通过 []获取的是列索引。如果想要获取行索引,则需要通过 loc或者 iloc属性来实现, lociloc的区别是, loc是通过名称获取,而 iloc是通过索引下标获取。

loc的除了能获取行索引外,还可以获取列索引。 .loc[row, col]的第二个参数即是获取列索引。示例代码如下:

获取行索引中11:33,"a"列的数据
df.loc["11":"33", "a"]

获取行索引中"11"和"a":"c"列的数据
df.loc["11", "a":"b"]

获取行索引中"11","33",和列索引中"a","c"列的数据
df.loc[["11", "33"], ["a", "b"]]

获取"a"列的所有数据
df.loc[:,"a"]

获取'11'行中的所有列
df.loc['11', :]

作用和 loc一样,区别是通过索引下标来实现的。示例代码如下:

获取第1-2行的所有列
df.iloc[1:3]

获取第1,3行的所有列
df.iloc[[1,3]]

获取第1行的第1-3列
df.iloc[1, 1:4]

四、重置索引

Pandas中重置索引有三种方法,分别是 set_indexreset_index以及 reindex以及直接修改 index属性。我们使用以下测试数据来作为讲解。

df = pd.DataFrame({'month': [1, 4, 7, 10],
                    'year': [2012, 2014, 2013, 2014],
                    'sale':[55, 40, 84, 31]})

输出结果如下:

monthyearsale012012551420144027201384310201431

如果在想使用某列作为 DataFrame的索引,那么可以使用 set_index(keys, drop=True)来实现。其中 keys是用于设置索引列的名称或者列表, drop代表是否要删除作为索引的列。 这个方法不会修改原始DataFrame对象。 示例代码如下:

df.set_index("month")

输出结果如下:

    year    sale
month
1   2012    55
4   2014    40
7   2013    84
10  2014    31

应用场景: 需要将 DataFrame中某列或多列设置为索引的情况下使用。

重新设置新的下标索引。使用 reset_index(drop=False)来实现。 drop代表是否删除原始索引。 这个方法不会修改原始DataFrame对象。 示例代码如下:

df.reset_index()

输出结果如下:

    month   year    sale
0   1   2012    55
1   4   2014    40
2   7   2013    84
3   10  2014    31

应用场景: 重新生成新的下标索引。

在即不使用原有列作为索引,以及不使用新的下标索引的时候。可以使用 reindex重新指定新的索引。 这个方法不会修改原始DataFrame对象。 使用 reindex有以下特点。

示例代码如下:

1. 添加新的索引
df.reindex([0,1,2,3,4])

2. 删除某个索引的行
df.reindex([0,2,3])

3. 修改索引顺序
df.reindex([2,3,1,0])

应用场景: 设置新的索引、修改索引顺序、删除某些索引。

直接修改 index属性也可以实现修改索引的目的,但是他有一个限制,就是新索引的数量,必须和原索引数量一致,否则会报错。 这个方法会修改原始DataFrame对象。 示例代码如下:

df.index = ['a', 'b', 'c', 'd' ]

还有一个需要注意的是,这种方法会直接修改原始 DataFrame对象。

应用场景: 需要修改原始 DataFrame对象的索引值。

Original: https://blog.csdn.net/qq_41404557/article/details/125898442
Author: Begin to change
Title: Pandas索引操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/750547/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球