关于Pandas版本: 本文基于 pandas2.1.2 编写。
关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。
Pandas稳定版更新及变动内容整合专题: Pandas稳定版更新及变动迭持续更新。
pandas.DataFrame.reindex
方法用于将 DataFrame
的索引 替换 为新的索引:
axis
参数指定。DataFrame
的数据将根据 新索引 指定的顺序 重新排列。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、使用 index
和 columns
参数明确指定新索引的作用对象:
(index=index_labels, columns=column_labels, ...)
2、使用 labels
参数和 axis
参数指定新索引的作用对象:
(labels, axis={'index', 'columns'}, ...)
?? 注意 :
官方建议使用第1种传参方法,这种方法更简单,可读性也更高。
labels : array-like, optional
labels
参数用于指定新索引,接受 array-like
对象传入。
索引(index)
使用,替换掉原始索引。axis
参数,则根据其指定的轴替换原索引。index
或 columns
其中一个参数被使用, 则labels
传入的新索引,会对另一个位置的原始索引 / 标签 进行替换。?? 注意 :
这是
DataFrame.reindex
方法的第1个参数,允许隐式传递,当你隐式把新索引直接传递给DataFrame.reindex
请记住,这个新索引将被传入到labels
参数。例如:df.reindex(['row1', 'row2', 'row3'])
等效于df.reindex(labels=['row1', 'row2', 'row3'])
如果你并不打算使用
labels
参数,新索引的数据,一定要显式传递给index
或columns
参数。官方不建议使用
labels
参数 详见 使用方法。
axis : int or str, optional
axis
用于控制 labels
参数传入的新索引,用来替换索引还是列名。axis
参数接受以下类型的传入:
0
代表用来替换索引,1
代表用来替换列名。index
代表用来替换索引, columns
代表用来替换列名。?? 注意 :
官方不建议使用axis
参数 详见 使用方法。
index : array-like, optional
index
指定新索引,用于替换 DataFrame
的原始索引。 接受 array-like 类型的数据传入。不能和 axis
参数一起使用。
index
参数即可。columns
参数配合使用。例columns : array-like, optional
columns
指定新的标签(列名),用于替换 DataFrame
的标签(列名) 接受array-like 类型的数据传入。不能和 axis
参数一起使用。
columns
参数即可。index
参数配合使用。例method : {None, ‘backfill’/’bfill’, ‘pad’/’ffill’, ‘nearest’}
如果重索引后,DataFrame
产生了缺失值,可以根据需要使用 method
参数进行填充: 例
?? 注意 :
method
参数仅适用于单调递增/递减 的 新索引/列名
copy : bool, default True
默认情况下,copy=True
这意味着重索引后的 DataFrame
是一个全新的对象,对其进行的数据修改,不会作用于原始数据。例
若指定 copy=False
将根据新索引和原始索引是否相同,产生如下结果:
level : int or name 例
如果 DataFrame
具有多层索引,或多层列名,可以使用 level
参数指定替换动作,作用于哪个层级。level
参数接受以下类型的传入:
fill_value : scalar, default np.nan
用于指定填充缺失值的值,默认为 NaN,但可以是任何“兼容”的值。例
limit : int, default None
当需要填充缺失值, limit
参数控制最大连续填充次数。默认为不限制,可以用整数指定最大次数。例
?? 注意 :
limit
只对method
参数的填充方法生效。
fill_value
使用固定值填充的次数,不受影响。
tolerance : optional
最大容差距离:例
当新索引和原始索引不一致,会产生缺失值。如果希望通过 method
参数进行插值,会进行【最近有效值】的判定。默认状况下,这个距离是不受限制的。
如果,你希望【最近有效值】有距离限制,可以使用 tolerance
参数指定一个最大容差距离。最大容差距离有以下注意事项:
【最近有效值】 应符合公式 abs(index[indexer] - target) <= tolerance
简单理解为:缺失值对应的新索引的索引值 减 最近目标值对应的新索引的索引值 小于等于 最大容差距离 即可判定为这个值是有效值
最大容差距离是一个标量值,它对所有值应用相同的tolerance;
也可以是 list-like
的值,它对每个元素应用可变的tolerance。
并且必须与索引相同大小,其 dtype 必须与索引的类型完全匹配。
?? 注意 :
tolerance
参数 只能和method
参数 同时使用。否则会引发ValueError
?? 相关方法
添加索引
重置索引(重置为数字索引)
仿制索引
测试文件下载:
本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。
若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。
示例: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行 | NaN | NaN |
第9行 | NaN | NaN |
第12行 | NaN | NaN |
在DataFrame里,之前并没有网址列,所以网址列会被NaN填充。并且,之前也没有第8行第9行,所以这两行也被NaN填充。
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
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2022-01-01 | 0 | 1 | 2 | 3 |
2022-01-02 | 4 | 5 | 6 | 7 |
2022-01-03 | 8 | 9 | 10 | 11 |
2022-01-04 | 12 | 13 | 14 | 15 |
# 构建新的索引
index_new = pd.date_range('2021-12-30', periods=10, freq='D')
# 重索引
df2 = df.reindex(index=index_new)
# 观察缺失值
df2
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2021-12-30 | NaN | NaN | NaN | NaN |
2021-12-31 | NaN | NaN | NaN | NaN |
2022-01-01 | 0.0 | 1.0 | 2.0 | 3.0 |
2022-01-02 | 4.0 | 5.0 | 6.0 | 7.0 |
2022-01-03 | 8.0 | 9.0 | 10.0 | 11.0 |
2022-01-04 | 12.0 | 13.0 | 14.0 | 15.0 |
2022-01-05 | NaN | NaN | NaN | NaN |
2022-01-06 | NaN | NaN | NaN | NaN |
2022-01-07 | NaN | NaN | NaN | NaN |
2022-01-08 | NaN | NaN | NaN | NaN |
3、使用 method
参数的 nearest
,用缺失值最近的有效数据填充(ffill,bfill请自行测试)
# 重索引
df2 = df.reindex(index=index_new, method='nearest')
# 观察新df
df2
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2021-12-30 | 0 | 1 | 2 | 3 |
2021-12-31 | 0 | 1 | 2 | 3 |
2022-01-01 | 0 | 1 | 2 | 3 |
2022-01-02 | 4 | 5 | 6 | 7 |
2022-01-03 | 8 | 9 | 10 | 11 |
2022-01-04 | 12 | 13 | 14 | 15 |
2022-01-05 | 12 | 13 | 14 | 15 |
2022-01-06 | 12 | 13 | 14 | 15 |
2022-01-07 | 12 | 13 | 14 | 15 |
2022-01-08 | 12 | 13 | 14 | 15 |
可以发现,缺失的数据都用其最近的有效数据填充了。
示例:当 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
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2022-01-01 | 1000 | 1 | 2 | 3 |
2022-01-02 | 4 | 5 | 6 | 7 |
2022-01-03 | 8 | 9 | 10 | 11 |
2022-01-04 | 12 | 13 | 14 | 15 |
可以发现,当 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
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2022-01-01 | 0 | 1 | 2 | 3 |
2022-01-02 | 4 | 5 | 6 | 7 |
2022-01-03 | 8 | 9 | 10 | 11 |
2022-01-04 | 12 | 13 | 14 | 15 |
可以发现,当 copy=False
如果新索引和原始索引不同,对新对象的数据修改,不会作用于原始数据。
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
speed | species | ||
---|---|---|---|
max | type | ||
class | name | ||
bird | falcon | 389.0 | fly |
parrot | 24.0 | fly | |
mammal | lion | 80.5 | run |
monkey | NaN | jump |
df2 = df.reindex(columns=['species', 'speed'], level=0)
df2
species | speed | ||
---|---|---|---|
type | max | ||
class | name | ||
bird | falcon | fly | 389.0 |
parrot | fly | 24.0 | |
mammal | lion | run | 80.5 |
monkey | jump | NaN |
df3 = df.reindex(index=['mammal', 'bird'], level='class')
df3
speed | species | ||
---|---|---|---|
max | type | ||
class | name | ||
mammal | lion | 80.5 | run |
monkey | NaN | jump | |
bird | falcon | 389.0 | fly |
parrot | 24.0 | fly |
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
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2022-01-04 | 12 | 13 | 14 | 15 |
2022-01-05 | 8888 | 8888 | 8888 | 8888 |
2022-01-06 | 8888 | 8888 | 8888 | 8888 |
2022-01-07 | 8888 | 8888 | 8888 | 8888 |
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
0 | 1 | 2 | 3 | |
---|---|---|---|---|
2022-01-04 | 12.0 | 13.0 | 14.0 | 15.0 |
2022-01-05 | 12.0 | 13.0 | 14.0 | 15.0 |
2022-01-06 | 12.0 | 13.0 | 14.0 | 15.0 |
2022-01-07 | NaN | NaN | NaN | NaN |
2022-01-08 | NaN | NaN | NaN | NaN |
2022-01-09 | NaN | NaN | NaN | NaN |
2022-01-10 | NaN | NaN | NaN | NaN |
2022-01-11 | NaN | NaN | NaN | NaN |
示例:当新索引和原始索引无法完全匹配,可以使用 tolerance
参数控制容差
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
a | b | |
---|---|---|
5 | 1 | 4 |
15 | 2 | 5 |
25 | 3 | 6 |
tolerance
限制容差距离,只有当 tolerance=5
,才会被视为最近有效数值。插值方可生效。df3 = df.reindex(index=index_new, method='ffill', tolerance=5)
# 观察结果
df3
a | b | |
---|---|---|
5 | 1 | 4 |
15 | 2 | 5 |
25 | 3 | 6 |