Pandas.DataFrame.reindex() 重索引 详解 含代码 含测试数据集 随Pandas版本持续更新

发布时间:2024年01月09日

关于Pandas版本: 本文基于 pandas2.1.2 编写。

关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。

Pandas稳定版更新及变动内容整合专题: Pandas稳定版更新及变动迭持续更新。

Pandas API参考所有内容目录

Pandas.DataFrame.reindex()

pandas.DataFrame.reindex 方法用于将 DataFrame 的索引 替换 为新的索引:

  • 被替换的可以是行索引(index),也可以是标签(labels),具体由 axis 参数指定。
  • DataFrame 的数据将根据 新索引 指定的顺序 重新排列
  • 新索引 中的某个行 / 列 的索引,如果在原始索引中不存在,那么替换索引后,此行 / 列,将被 缺失值(NA/NaN) 填充。

pandas.DataFrame.reindex 方法常被用于:

  • 索引对齐;
  • 行的重新排列;
  • 列的重新排列;
  • 两个相似 DataFrame 的数据对比。

语法:

DataFrame.reindex(labels=None, * , index=None, columns=None, axis=None, method=None, copy=None, level=None, fill_value=nan, limit=None, tolerance=None)

返回值:

  • DataFrame with changed index

    修改索引后的 DataFrame

使用方法:

pandas.DataFrame.reindex 对于 替换目标 有两种传参方法:

  • 1、使用 indexcolumns 参数明确指定新索引的作用对象:

    • (index=index_labels, columns=column_labels, ...)
  • 2、使用 labels 参数和 axis 参数指定新索引的作用对象:

    • (labels, axis={'index', 'columns'}, ...)

?? 注意 :
官方建议使用第1种传参方法,这种方法更简单,可读性也更高。

参数说明:

labels 指定新索引

  • labels : array-like, optional

    labels 参数用于指定新索引,接受 array-like 对象传入。

    • 默认会使用新索引作为 索引(index) 使用,替换掉原始索引。
    • 如果使用了 axis参数,则根据其指定的轴替换原索引。
    • 如果 indexcolumns 其中一个参数被使用, 则labels传入的新索引,会对另一个位置的原始索引 / 标签 进行替换。

?? 注意 :

  • 这是 DataFrame.reindex 方法的第1个参数,允许隐式传递,当你隐式把新索引直接传递给 DataFrame.reindex 请记住,这个新索引将被传入到labels 参数。例如:df.reindex(['row1', 'row2', 'row3']) 等效于 df.reindex(labels=['row1', 'row2', 'row3'])

  • 如果你并不打算使用 labels 参数,新索引的数据,一定要显式传递indexcolumns 参数。

  • 官方不建议使用 labels 参数 详见 使用方法

axis 指定目标轴

  • axis : int or str, optional

    axis 用于控制 labels 参数传入的新索引,用来替换索引还是列名。axis 参数接受以下类型的传入:

    • int: 0 代表用来替换索引,1 代表用来替换列名。
    • str: 如果设置为 index 代表用来替换索引, columns 代表用来替换列名。

?? 注意 :
官方不建议使用 axis 参数 详见 使用方法

index 指定新索引

  • index : array-like, optional

    index 指定新索引,用于替换 DataFrame 的原始索引。 接受 array-like 类型的数据传入。不能和 axis 参数一起使用。

    • 如果只需要替换索引,则只使用 index 参数即可。
    • 如果同时需要替换标签(列名),可以和 columns 参数配合使用。

columns 指定新标签(列名)

  • columns : array-like, optional

    columns 指定新的标签(列名),用于替换 DataFrame 的标签(列名) 接受array-like 类型的数据传入。不能和 axis 参数一起使用。

    • 如果只需要替换列名,则只使用 columns 参数即可。
    • 如果同时需要替换标签(列名),可以和 index 参数配合使用。

method 缺失值的插值方法

  • method : {None, ‘backfill’/’bfill’, ‘pad’/’ffill’, ‘nearest’}

    如果重索引后,DataFrame 产生了缺失值,可以根据需要使用 method 参数进行填充:

    • ‘pad’ 或 ’ffill’ : 使用缺失值 前一个有效值 填充缺失值;
    • ‘backfill’ 或 ’bfill’ : 使用缺失值 后一个有效值 填充缺失值;
    • ‘nearest’ : 使用缺失值 最近的 填充缺失值;

?? 注意 :
method 参数仅适用于单调递增/递减新索引/列名

copy 是否创建原始数据副本

  • copy : bool, default True

    默认情况下,copy=True 这意味着重索引后的 DataFrame 是一个全新的对象,对其进行的数据修改,不会作用于原始数据。

    若指定 copy=False 将根据新索引和原始索引是否相同,产生如下结果:

    • 新索引和原始索引相同:视图模式,新DataFrame对象的数据修改,会作用于原始DataFrame
    • 新索引和原始索引不同:拷贝模式,自动创建一个全新的对象,新DataFrame对象的数据修改,不会作用于原始DataFrame

level 指定重索引级别

  • level : int or name

    如果 DataFrame 具有多层索引,或多层列名,可以使用 level 参数指定替换动作,作用于哪个层级。level 参数接受以下类型的传入:

    • int: 层级编号的整数(从0开始);
    • name: 层级的名称。

fill_value 用指定的值,填充缺失值

  • fill_value : scalar, default np.nan

    用于指定填充缺失值的值,默认为 NaN,但可以是任何“兼容”的值。

limit 最大连续填充次数

  • limit : int, default None

    当需要填充缺失值, limit 参数控制最大连续填充次数。默认为不限制,可以用整数指定最大次数。

    ?? 注意 :

    limit 只对 method 参数的填充方法生效。

    fill_value 使用固定值填充的次数,不受影响。

tolerance 最大容差距离

  • tolerance : optional

    最大容差距离:

    当新索引和原始索引不一致,会产生缺失值。如果希望通过 method 参数进行插值,会进行【最近有效值】的判定。默认状况下,这个距离是不受限制的。

    如果,你希望【最近有效值】有距离限制,可以使用 tolerance 参数指定一个最大容差距离。最大容差距离有以下注意事项:

    • 【最近有效值】 应符合公式 abs(index[indexer] - target) <= tolerance 简单理解为:缺失值对应的新索引的索引值最近目标值对应的新索引的索引值 小于等于 最大容差距离 即可判定为这个值是有效值

    • 最大容差距离是一个标量值,它对所有值应用相同的tolerance;

    • 也可以是 list-like 的值,它对每个元素应用可变的tolerance。

    • 并且必须与索引相同大小,其 dtype 必须与索引的类型完全匹配。

    ?? 注意 :
    tolerance 参数 只能和 method 参数 同时使用。否则会引发 ValueError

相关方法:

?? 相关方法


示例:

测试文件下载:

本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。

若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。

测试文件下载位置.png


示例:index参数和columns参数配合使用,同时替换DataFrame的索引和列名。对应不上的数据会被NaN填充

import pandas as pd

# 构建演示数据
index = ['第1行', '第2行', '第3行', '第4行', '第5行']
data = {'站点':['搜狐', '雅虎', '网易', '腾讯', '米哈游'], '响应时间':[0.04, 0.02, 0.07, 0.08, 1.0]}
df = pd.DataFrame(data, index=index)

# 构建新索引,和新列名
index_new = ['第1行', '第2行', '第3行', '第8行', '第9行', '第12行']
columns_new = ['站点','网址']

# 尝试重索引,让数据重新排列
df2 = df.reindex(index=index_new, columns=columns_new)

# 查看重索引后的df
df2
站点网址
第1行搜狐NaN
第2行雅虎NaN
第3行网易NaN
第8行NaNNaN
第9行NaNNaN
第12行NaNNaN

在DataFrame里,之前并没有网址列,所以网址列会被NaN填充。并且,之前也没有第8行第9行,所以这两行也被NaN填充。


示例:填充缺失值

  • 1、构建演示数据,并查看原始数据
import pandas as pd
import numpy as np

# 构建演示数据
data = np.arange(16).reshape(4, 4)
date = pd.date_range('2022-01-01', periods=4, freq='D')
df = pd.DataFrame(data, index=date)

# 查看原始数据
df
0123
2022-01-010123
2022-01-024567
2022-01-03891011
2022-01-0412131415
  • 2、重索引之后,观察缺失值
# 构建新的索引
index_new = pd.date_range('2021-12-30', periods=10, freq='D')

# 重索引
df2 = df.reindex(index=index_new)

# 观察缺失值
df2
0123
2021-12-30NaNNaNNaNNaN
2021-12-31NaNNaNNaNNaN
2022-01-010.01.02.03.0
2022-01-024.05.06.07.0
2022-01-038.09.010.011.0
2022-01-0412.013.014.015.0
2022-01-05NaNNaNNaNNaN
2022-01-06NaNNaNNaNNaN
2022-01-07NaNNaNNaNNaN
2022-01-08NaNNaNNaNNaN

3、使用 method 参数的 nearest ,用缺失值最近的有效数据填充(ffill,bfill请自行测试)

# 重索引
df2 = df.reindex(index=index_new, method='nearest')

# 观察新df
df2
0123
2021-12-300123
2021-12-310123
2022-01-010123
2022-01-024567
2022-01-03891011
2022-01-0412131415
2022-01-0512131415
2022-01-0612131415
2022-01-0712131415
2022-01-0812131415

可以发现,缺失的数据都用其最近的有效数据填充了。


示例:当 copy=False 如果新索引和原始索引相同,将使用视图模式,对新对象的数据修改,会作用于原始数据

import pandas as pd
import numpy as np

# 构建演示数据
data = np.arange(16).reshape(4, 4)
date = pd.date_range('2022-01-01', periods=4, freq='D')
df = pd.DataFrame(data, index=date)

# 使用相同的索引重索引
df2 = df.reindex(index=date, copy=False)

# 修改df2的值
df2.iloc[0,0] = 1000

# 观察原始数据
df
0123
2022-01-011000123
2022-01-024567
2022-01-03891011
2022-01-0412131415

可以发现,当 copy=False 如果新索引和原始索引相同,对新对象的数据修改,会作用于原始数据。


示例:当 copy=False 如果新索引和原始索引不同,将使用拷贝模式,对新对象的数据修改,不会作用于原始数据。这等效于 copy=True

import pandas as pd
import numpy as np

# 构建演示数据
data = np.arange(16).reshape(4, 4)
date = pd.date_range('2022-01-01', periods=4, freq='D')
df = pd.DataFrame(data, index=date)

# 使用不同的索引重索引
date_new = pd.date_range('2022-01-04', periods=4, freq='D')
df2 = df.reindex(index=date_new, copy=False)

# 修改df2的值
df2.iloc[0,0] = 1000

# 观察原始数据
df
0123
2022-01-010123
2022-01-024567
2022-01-03891011
2022-01-0412131415

可以发现,当 copy=False 如果新索引和原始索引不同,对新对象的数据修改,不会作用于原始数据。


示例:多层索引的reindex

  • 1、构建演示数据
import pandas as pd

index = pd.MultiIndex.from_tuples([('bird', 'falcon'),
                                   ('bird', 'parrot'),
                                   ('mammal', 'lion'),
                                   ('mammal', 'monkey')],
                                  names=['class', 'name'])

columns = pd.MultiIndex.from_tuples([('speed', 'max'),
                                     ('species', 'type')])

df = pd.DataFrame([(389.0, 'fly'),
                   (24.0, 'fly'),
                   (80.5, 'run'),
                   (np.nan, 'jump')],
                  index=index,
                  columns=columns)

df
speedspecies
maxtype
classname
birdfalcon389.0fly
parrot24.0fly
mammallion80.5run
monkeyNaNjump
  • 2、使用重索引,调换顶层列名 d的shunxu顺序
df2 = df.reindex(columns=['species', 'speed'], level=0)
df2
speciesspeed
typemax
classname
birdfalconfly389.0
parrotfly24.0
mammallionrun80.5
monkeyjumpNaN
  • 3、使用重索引,调换顶层索引bird和mammal的顺序
df3 = df.reindex(index=['mammal', 'bird'], level='class')
df3
speedspecies
maxtype
classname
mammallion80.5run
monkeyNaNjump
birdfalcon389.0fly
parrot24.0fly


示例:指定缺失值的填充值

import pandas as pd
import numpy as np

# 构建演示数据
data = np.arange(16).reshape(4, 4)
date = pd.date_range('2022-01-01', periods=4, freq='D')
df = pd.DataFrame(data, index=date)

# 使用不同的索引重索引,填充产生的缺失值
date_new = pd.date_range('2022-01-04', periods=4, freq='D')
df2 = df.reindex(index=date_new, fill_value=8888)

# 观察结果
df2
0123
2022-01-0412131415
2022-01-058888888888888888
2022-01-068888888888888888
2022-01-078888888888888888


示例:指定缺失值填充最大连续填充次数为2次

import pandas as pd
import numpy as np

# 构建演示数据
data = np.arange(16).reshape(4, 4)
date = pd.date_range('2022-01-01', periods=4, freq='D')
df = pd.DataFrame(data, index=date)

# 使用不同的索引重索引,填充产生的缺失值
date_new = pd.date_range('2022-01-04', periods=8, freq='D')
df2 = df.reindex(index=date_new, method='nearest', limit=2)

# 观察结果
df2
0123
2022-01-0412.013.014.015.0
2022-01-0512.013.014.015.0
2022-01-0612.013.014.015.0
2022-01-07NaNNaNNaNNaN
2022-01-08NaNNaNNaNNaN
2022-01-09NaNNaNNaNNaN
2022-01-10NaNNaNNaNNaN
2022-01-11NaNNaNNaNNaN


示例:当新索引和原始索引无法完全匹配,可以使用 tolerance 参数控制容差

  • 1、默认状态下,新索引和原始索引如果无法完全匹配,会产生缺失值,在使用method插值时,是不会关注新老索引距离问题的。
import pandas as pd
import numpy as np

# 构建演示数据
data = {'a':[1, 2, 3], 'b':[4, 5, 6]}
index = [0, 10, 20]
df = pd.DataFrame(data, index=index)

# 使用不同的索引重索引,填充产生的缺失值
index_new = [5, 15, 25]
df2 = df.reindex(index=index_new, method='ffill')

# 观察结果
df2
ab
514
1525
2536
  • 2、如果,使用tolerance 限制容差距离,只有当 tolerance=5 ,才会被视为最近有效数值。插值方可生效。
df3 = df.reindex(index=index_new, method='ffill', tolerance=5)

# 观察结果
df3
ab
514
1525
2536
文章来源:https://blog.csdn.net/mingqinsky/article/details/135447514
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。