📌  相关文章
📜  根据最近的 DateTime 合并两个 Pandas DataFrame(1)

📅  最后修改于: 2023-12-03 15:10:49.232000             🧑  作者: Mango

根据最近的 DateTime 合并两个 Pandas DataFrame

有时候,在 Pandas 中,我们需要根据两个 DataFrame 中的 DateTime 列合并它们。但是又不能简单地使用 Pandas 中的 merge() 函数,因为我们需要根据最近的 DateTime 来匹配行,而不是严格的匹配。

下面是一种方法,可以帮助您根据最近的 DateTime 合并两个 Pandas DataFrame。

假设您有两个 DataFrame,一个是 df1,它具有 DateValue 列,例如:

import pandas as pd

df1 = pd.DataFrame({
    'Date': ['2022-01-01', '2022-01-02', '2022-01-03'], 
    'Value': [100, 200, 300]
})

另一个是 df2,它也具有 DateValue 列,但是其日期范围比 df1 更广泛:

df2 = pd.DataFrame({
    'Date': ['2022-01-01', '2022-01-03', '2022-01-05'], 
    'Value': [400, 500, 600]
})
第一步:将 DateTime 转换为 Pandas DatetimeIndex

首先,我们需要将两个 DataFrame 的 Date 列转换为 Pandas 中的 DatetimeIndex:

df1_idx = pd.DatetimeIndex(df1['Date'])
df1.index = df1_idx
df1 = df1.drop('Date', axis=1)

df2_idx = pd.DatetimeIndex(df2['Date'])
df2.index = df2_idx
df2 = df2.drop('Date', axis=1)

这里,我们使用 pd.DatetimeIndex() 函数来创建一个新的 DatetimeIndex,然后将其设置为 DataFrame 的索引。最后,我们删除原始的 Date 列,因为我们不需要它了。

第二步:使用 resample() 和 bfill() 函数合并两个 DataFrame

接下来,我们使用 Pandas 的 resample() 方法,将 df2 的时间范围与 df1 相同的数据。resample() 方法将数据按照给定的频率进行重新抽样,这里我们只需要使用 "D",表示天。

我们还需要使用 bfill() 方法,将 NaN 值向前填充,以根据最近的 DateTime 匹配数据。

# resample and bfill
df2_resampled = df2.resample('D').bfill()

# merge two DataFrames
result = pd.concat([df1, df2_resampled], axis=1)
完整代码片段

完整的代码如下所示:

import pandas as pd

df1 = pd.DataFrame({
    'Date': ['2022-01-01', '2022-01-02', '2022-01-03'], 
    'Value': [100, 200, 300]
})

df2 = pd.DataFrame({
    'Date': ['2022-01-01', '2022-01-03', '2022-01-05'], 
    'Value': [400, 500, 600]
})

# convert Date column to DatetimeIndex
df1_idx = pd.DatetimeIndex(df1['Date'])
df1.index = df1_idx
df1 = df1.drop('Date', axis=1)

df2_idx = pd.DatetimeIndex(df2['Date'])
df2.index = df2_idx
df2 = df2.drop('Date', axis=1)

# resample and bfill
df2_resampled = df2.resample('D').bfill()

# merge two DataFrames
result = pd.concat([df1, df2_resampled], axis=1)

现在,您可以根据最近的 DateTime 合并两个 Pandas DataFrame。