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

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

本节目录

  • Pandas.DataFrame.reindex_like()
  • 语法:
  • 返回值:
  • 参数说明:
  • other 指定另一个 DataFrame 对象(仿制索引的目标)
  • method 缺失值的填充方法
  • copy 是否创建原始数据副本
  • limit 最大连续填充次数
  • tolerance 最大容差距离
  • 相关方法:
  • 示例:


Pandas.DataFrame.reindex_like()

用另一个 DataFrame 的索引(index)、列名,替换当前DataFrame的索引和列名。

  • 默认状态下 copy=True,这意味着将创建新的 DataFrame对象,无论新索引、列名和原始数据的索引、列名是否相同。
  • 索引仿制后,如果新索引、新列名,对于原始 DataFrame 产生异同,对应位置的数据将会被填充为缺失值(Nan)。
  • 新索引、新列名的数据类型,必须和原始索引、原始列名的数据类型相同。否则数据将全是NaN。例如数字1 和字符串 1 并不相同。

这个方法的目的是将一个 DataFrame 对象的索引调整为另一个 DataFrame 对象的索引,以便它们具有相同的索引结构。

语法:

DataFrame.reindex_like(other, method=None, copy=None, limit=None, tolerance=None)

返回值:

  • Series or DataFrame
    与调用者相同类型的对象,但在每个轴上具有更改的索引。

参数说明:

other 指定另一个 DataFrame 对象(仿制索引的目标)

  • other : Object of the same data type
    指定另一个具有相同数据类型(索引、列名)的 DataFrame 对象。

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

⚠️ 注意 :

copy 参数将改变 pandas 3.0 中的行为。默认情况下会启用 Copy-on-Write,这意味着所有带有 copy 参数的方法都将使用惰性复制机制来推迟复制并忽略 copy 参数。 copy 参数将在 pandas 的未来版本中删除。您已经可以通过启用写入时复制 pd.options.mode.copy_on_write = True 来获得未来的行为和改进。

limit 最大连续填充次数

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

⚠️ 注意 :

limit 需要和 method 参数配合使用。

tolerance 最大容差距离

  • tolerance:optional
    最大容差距离:当新索引和原始索引不一致,会产生缺失值。如果希望通过 method 参数进行插值,会进行【最近有效值】的判定。默认状况下,这个距离是不受限制的。
    如果,你希望【最近有效值】有距离限制,可以使用 tolerance 参数指定一个最大容差距离。最大容差距离有以下注意事项:
  • 【最近有效值】 应符合公式 abs(index[indexer] - target) <= tolerance 简单理解为:缺失值对应的新索引的索引值最近目标值对应的新索引的索引值 小于等于 最大容差距离 即可判定为这个值是有效值
  • 最大容差距离是一个标量值,它对所有值应用相同的tolerance;
  • 也可以是 list-like 的值,它对每个元素应用可变的tolerance。
  • 并且必须与索引相同大小,其 dtype 必须与索引的类型完全匹配。

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

示例:

测试文件下载:

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

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

dataframe 索引名字英文 dataframe如何索引_dataframe 索引名字英文

示例:新索引和原始索引的数据类型必须相同,会产生数据全是缺失值(NaN)的问题

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = ['1', '2', '3']
data2 = {'111':['a1', 'a2', 'a3'], '222':['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2)

# 观察原始数据
print(f"以下为运行结果:\n{'*' * 50}\n原始数据:\n{df1}\n原始数据索引和列名的数据类型:\n{df1.axes}\n\n用来提取索引和列名的df2:\n{df2}\ndf2索引和列名的数据类型:\n{df2.axes}\n\n原始数据仿制索引后的df3:\n{df3}\n原始数据仿制索引后的索引、列名数据类型:\n{df3.axes}\n{'*' * 50}")
以下为运行结果:
**************************************************
原始数据:
  111 222
1  a1  b1
2  a2  b2
3  a3  b3
原始数据索引和列名的数据类型:
[Index([1, 2, 3], dtype='int64'), Index([111, 222], dtype='int64')]

用来提取索引和列名的df2:
  111 222
1  a1  b1
2  a2  b2
3  a3  b3
df2索引和列名的数据类型:
[Index(['1', '2', '3'], dtype='object'), Index(['111', '222'], dtype='object')]

原始数据仿制索引后的df3:
   111  222
1  NaN  NaN
2  NaN  NaN
3  NaN  NaN
原始数据仿制索引后的索引、列名数据类型:
[Index(['1', '2', '3'], dtype='object'), Index(['111', '222'], dtype='object')]
**************************************************

由上结果可见,由于数据类型的不同,即使新索引、新列名的值和原始索引、原始列名的值 看起来一样,但实际上并不相同。所有数据都被填充为缺失值(NaN)

示例:填充缺失值,仅使用 ffill 演示,其他的填充方法请自行测试

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [1, 4, 5]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, method='ffill')
df3



111

222

1

a1

b1

4

a3

b3

5

a3

b3

由上面结果可以发现,索引 4 因为无法在原始数据中找到有效数据,使用 method=‘ffill’ 从原始数据中的 第3 行取数据进行了填充。

示例:默认状态下 copy=True,仿制索引后的新对象的数据修改,不会作用于原始数据

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [1, 4, 5]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2)

# 修改df3的数据
df3.iloc[0,0] = 8888

# 观察原始数据
df1



111

222

1

a1

b1

2

a2

b2

3

a3

b3

示例:若指定 copy=False ,新索引、列名和原始索引、列名 相同,则使用视图模式,重置索引后的DataFrame的 数据修改会作用于原始数据

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [1, 2, 3]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, copy=False)

# 修改df3的数据
df3.iloc[0,0] = 8888

# 观察原始数据
df1



111

222

1

8888

b1

2

a2

b2

3

a3

b3

示例:若指定 copy=False ,新索引、列名和原始索引、列名 不同,则使用拷贝模式,重置索引后的DataFrame的 数据修改不会作用于原始数据

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [1, 4, 6]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, copy=False)

# 修改df3的数据
df3.iloc[0,0] = 8888

# 观察原始数据
df1



111

222

1

a1

b1

2

a2

b2

3

a3

b3

示例:控制缺失值填充的最大连续填充数

import pandas as pd

# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [1, 4, 6]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, method='ffill', limit=1)
df3



111

222

1

a1

b1

4

a3

b3

6

NaN

NaN

由上面结果可以发现,当最大连续填充数 limit=1 只在新索引的 4 的位置填充了,后面的一个虽然紧挨着上面的行,但是并没有被填充。

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

  • 1、默认状态下,新索引和原始索引如果无法完全匹配,会产生缺失值,在使用method插值时,是不会关注新老索引距离问题的。
# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [6, 7, 8]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, method='ffill')
df3



111

222

6

a3

b3

7

a3

b3

8

a3

b3

  • 2、如果,使用tolerance 限制容差距离,只有当 <=4 ,才会被视为最近有效数值。插值方可生效。
# df1
index1 = [1, 2, 3]
data1 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df1 = pd.DataFrame(data=data1, index=index1)

# df2
index2 = [6, 7, 8]
data2 = {111:['a1', 'a2', 'a3'], 222:['b1', 'b2', 'b3']}
df2 = pd.DataFrame(data=data2, index=index2)

# df3 = 仿制索引后的df1
df3 = df1.reindex_like(df2, method='ffill', tolerance=4)
df3



111

222

6

a3

b3

7

a3

b3

8

NaN

NaN

由上述结果可见,因为 8-3 >4 所以新索引8的位置,并没有被填充。

8-3 >4:

8是新索引缺失值对应的索引值

3是老索引中最近的有效值