提问人:Aleksandra 提问时间:11/17/2023 最后编辑:petezurichAleksandra 更新时间:11/17/2023 访问量:41
按最接近的较低日期或相等日期合并数据帧
Merge dataframes by the nearest lower or equal date
问:
我有两个数据框:
df1 = pd.DataFrame({'ID':['A', 'A', 'B', 'B'],
'Date':['31.08.2023', '12.09.2023', '13.09.2023', '20.08.2023']})
df2 = pd.DataFrame({'ID':['A', 'A', 'A', 'B', 'B'],
'Date':['30.08.2023', '14.09.2023', '10.09.2023', '28.09.2023', '19.08.2023']})
我想向 df1 添加两个新列,每个 ID 中都有最接近的上下日期,因此此示例中的期望输出将如下所示:
编号 | 日期 | DATE_UP | DATE_DOWN |
---|---|---|---|
一个 | 31.08.2023 | 10.09.2023 | 30.08.2023 |
一个 | 12.09.2023 | 14.09.2023 | 10.09.2023 |
B | 13.09.2023 | 28.09.2023 | 19.08.2023 |
B | 20.08.2023 | 28.09.2023 | 19.08.2023 |
我知道有一个 pandas 函数 merge_asof(),但它仅适用于最近的合并。 对于如何有效地做到这一点的任何想法,我都会非常满意。
答:
2赞
Panda Kim
11/17/2023
#1
法典
您可以通过以下方式解决它。merge_asof 不仅适用于最近的合并。即使最近不是默认值,默认值是向后。merge_asof
首先制作名为“Date1”的日期时间列并排序
df1['Date1'] = pd.to_datetime(df1['Date'], dayfirst=True)
df1 = df1.sort_values('Date1')
df2['Date1'] = pd.to_datetime(df2['Date'], dayfirst=True)
df2 = df2.sort_values('Date1')
DF1:
ID Date Date1
3 B 20.08.2023 2023-08-20
0 A 31.08.2023 2023-08-31
1 A 12.09.2023 2023-09-12
2 B 13.09.2023 2023-09-13
DF2:
ID Date Date1
4 B 19.08.2023 2023-08-19
0 A 30.08.2023 2023-08-30
2 A 10.09.2023 2023-09-10
1 A 14.09.2023 2023-09-14
3 B 28.09.2023 2023-09-28
接下来使用前进和后退(默认)merge_asof
tmp = pd.merge_asof(df1.reset_index(), df2, on='Date1', by='ID',
direction='forward', suffixes=['', '_up'])
out = pd.merge_asof(tmp, df2, on='Date1', by='ID', suffixes=['', '_down'])\
.drop('Date1', axis=1).set_index('index').sort_index().rename_axis('')
外:
ID Date Date_up Date_down
0 A 31.08.2023 10.09.2023 30.08.2023
1 A 12.09.2023 14.09.2023 10.09.2023
2 B 13.09.2023 28.09.2023 19.08.2023
3 B 20.08.2023 28.09.2023 19.08.2023
0赞
Kamil
11/17/2023
#2
创建数据帧
import pandas as pd
df1 = pd.DataFrame({
'ID': ['A', 'A', 'B', 'B'],
'Date': ['31.08.2023', '12.09.2023', '13.09.2023', '20.08.2023']
})
df2 = pd.DataFrame({
'ID': ['A', 'A', 'A', 'B', 'B'],
'Date': ['30.08.2023', '14.09.2023', '10.09.2023', '28.09.2023', '19.08.2023']
})
将“日期”列转换为日期时间
df1['Date'] = pd.to_datetime(df1['Date'], dayfirst=True)
df2['Date'] = pd.to_datetime(df2['Date'], dayfirst=True)
按“ID”和“Date”对数据帧进行排序
df1 = df1.sort_values(by=['ID', 'Date'])
df2 = df2.sort_values(by=['ID', 'Date'])
查找最近的较高日期 (DATE_UP)
df1['DATE_UP'] = df1.apply(lambda row: df2[(df2['ID'] == row['ID']) & (df2['Date'] > row['Date'])]['Date'].min(), axis=1)
查找最近的较低日期 (DATE_DOWN)
df1['DATE_DOWN'] = df1.apply(lambda row: df2[(df2['ID'] == row['ID']) & (df2['Date'] < row['Date'])]['Date'].max(), axis=1)
将 'Date', 'DATE_UP', 'DATE_DOWN' 转换回原始字符串格式
df1['Date'] = df1['Date'].dt.strftime('%d.%m.%Y')
df1['DATE_UP'] = df1['DATE_UP'].dt.strftime('%d.%m.%Y')
df1['DATE_DOWN'] = df1['DATE_DOWN'].dt.strftime('%d.%m.%Y')
评论