Python Pandas - 重新索引



重新索引是 Pandas 中一个强大且基本的操作,允许您将数据与一组新的标签对齐。无论您使用的是行还是列,重新索引都可以控制数据如何与您指定的标签对齐。

此操作在处理时间序列数据、对齐来自不同来源的数据集或简单地重新组织数据以匹配特定结构时特别有用。

什么是重新索引?

Pandas 中的重新索引是指使您的数据符合指定轴(行或列)上的一组新标签的过程。此过程可以完成以下几个任务:

  • 重新排序:重新排序现有数据以匹配一组新的标签。

  • 插入缺失值:如果新集合中的标签在原始数据中不存在,Pandas 将为该标签插入缺失值 (NaN)。

  • 填充缺失数据:您可以指定如何使用各种填充方法来填充重新索引导致的缺失值。

reindex() 方法是 Pandas 中执行重新索引的主要工具。它允许您修改 Pandas 数据结构的行和列标签。

重新索引中使用的关键方法

  • reindex():此方法用于将现有数据结构与新的索引(或列)对齐。它可以重新排序和/或插入缺失的标签。

  • reindex_like():此方法允许您将一个 DataFrame 或 Series 重新索引以匹配另一个。当您希望确保两个数据结构类似地对齐时,此方法很有用。

  • 填充方法:当重新索引引入 NaN 值时,您可以使用 ffill、bfill 和 nearest 等方法填充它们。

示例:重新索引 Pandas Series

以下示例演示了使用 reindex() 方法重新索引 Pandas Series 对象。在这种情况下,“f”标签在原始 Series 中不存在,因此它在输出重新索引的 Series 中显示为 NaN。

import pandas as pd
import numpy as np

s = pd.Series(np.random.randn(5), index=["a", "b", "c", "d", "e"])
print("Original Series:\n",s)

s_reindexed = s.reindex(["e", "b", "f", "d"])
print('\nOutput Reindexed Series:\n',s_reindexed)

执行上述代码后,您将获得以下输出:

Original Series:
 a    0.148874
b    0.592275
c   -0.903546
d    1.031230
e   -0.254599
dtype: float64

Output Reindexed Series:
 e   -0.254599
b    0.592275
f         NaN
d    1.031230
dtype: float64

示例:重新索引 DataFrame

考虑以下使用 reindex() 方法重新索引 DataFrame 的示例。对于 DataFrame,您可以重新索引行(索引)和列。

import pandas as pd
import numpy as np

N=5

df = pd.DataFrame({
   'A': pd.date_range(start='2016-01-01',periods=N,freq='D'),
   'x': np.linspace(0,stop=N-1,num=N),
   'y': np.random.rand(N),
   'C': np.random.choice(['Low','Medium','High'],N).tolist(),
   'D': np.random.normal(100, 10, size=(N)).tolist()
})

print("Original DataFrame:\n", df)

#reindex the DataFrame
df_reindexed = df.reindex(index=[0,2,5], columns=['A', 'C', 'B'])

print("\nOutput Reindexed DataFrame:\n",df_reindexed)

输出如下:

Original DataFrame:
            A    x         y       C           D
0 2016-01-01  0.0  0.513990  Medium  118.143385
1 2016-01-02  1.0  0.751248     Low   91.041201
2 2016-01-03  2.0  0.332970  Medium  100.644345
3 2016-01-04  3.0  0.723816    High  108.810386
4 2016-01-05  4.0  0.376326    High  101.346443

Output Reindexed DataFrame:
            A       C   B
0 2016-01-01  Medium NaN
2 2016-01-03  Medium NaN
5        NaT     NaN NaN

重新索引以与其他对象对齐

有时,您可能需要重新索引一个 DataFrame 以使其与另一个 DataFrame 对齐。reindex_like() 方法允许您无缝地执行此操作。

示例

以下示例演示了如何使用 reindex_like() 方法重新索引一个 DataFrame (df1) 以匹配另一个 DataFrame (df2)。

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randn(10,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(7,3),columns=['col1','col2','col3'])

df1 = df1.reindex_like(df2)
print(df1)

输出如下:

          col1         col2         col3
0    -2.467652    -1.211687    -0.391761
1    -0.287396     0.522350     0.562512
2    -0.255409    -0.483250     1.866258
3    -1.150467    -0.646493    -0.222462
4     0.152768    -2.056643     1.877233
5    -1.155997     1.528719    -1.343719
6    -1.015606    -1.245936    -0.295275

注意:此处,df1 DataFrame 被更改并像 df2 一样重新索引。列名应匹配,否则将为整个列标签添加 NAN。

重新索引时的填充

reindex() 方法提供了一个可选参数 method 用于填充缺失值。可用的方法包括:

  • pad/ffill:向前填充值。

  • bfill/backfill:向后填充值。

  • nearest:从最近的索引值填充。

示例

以下示例演示了 ffill 方法的工作原理。

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randn(6, 3), columns=['col1', 'col2', 'col3'])
df2 = pd.DataFrame(np.random.randn(2, 3), columns=['col1', 'col2', 'col3'])

# Padding NaNs
print(df2.reindex_like(df1))

# Now fill the NaNs with preceding values
print("Data Frame with Forward Fill:")
print(df2.reindex_like(df1, method='ffill'))

输出如下:

         col1        col2       col3
0    1.311620   -0.707176   0.599863
1   -0.423455   -0.700265   1.133371
2         NaN         NaN        NaN
3         NaN         NaN        NaN
4         NaN         NaN        NaN
5         NaN         NaN        NaN

Data Frame with Forward Fill:
         col1        col2        col3
0    1.311620   -0.707176    0.599863
1   -0.423455   -0.700265    1.133371
2   -0.423455   -0.700265    1.133371
3   -0.423455   -0.700265    1.133371
4   -0.423455   -0.700265    1.133371
5   -0.423455   -0.700265    1.133371

注意:最后四行已填充。

重新索引时填充的限制

limit 参数提供了对重新索引时填充的额外控制。limit 指定连续匹配的最大计数。

示例

让我们考虑以下示例来了解指定填充限制:

import pandas as pd
import numpy as np
 
df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])

# Padding NaNs
print(df2.reindex_like(df1))

# Now fill the NaNs with preceding values
print("Data Frame with Forward Fill limiting to 1:")
print(df2.reindex_like(df1, method='ffill', limit=1))

输出如下:

         col1        col2        col3
0    0.247784    2.128727    0.702576
1   -0.055713   -0.021732   -0.174577
2         NaN         NaN         NaN
3         NaN         NaN         NaN
4         NaN         NaN         NaN
5         NaN         NaN         NaN

Data Frame with Forward Fill limiting to 1:
         col1        col2        col3
0    0.247784    2.128727    0.702576
1   -0.055713   -0.021732   -0.174577
2   -0.055713   -0.021732   -0.174577
3         NaN         NaN         NaN
4         NaN         NaN         NaN
5         NaN         NaN         NaN

注意:向前填充 (ffill) 仅限于一行。

广告