通过合并另一个数据帧在数据帧中创建列



这是我的数据帧1 df1:

ID    Date
0   90  02/01/2021
1   101 01/31/2021
2   30  12/31/2021

我的数据帧2 df2:

ID  01/01/2021  02/01/2021  12/01/2021
0   90    20           14          22
1   101   15           10          5
2   30    12           9           13

在df1中,我需要创建一个列"Attendance"。它应该包含df2中可用的最接近日期列的数据,相对于"ID"的df1中的"日期"列。

根据df1:的"日期"的最近日期

2021年1月2日-->2021年1月2日

2021年1月31日-->2021年1月2日

2021年12月31日-->2022年1月1日,如果不可用,请考虑df2的最新日期栏。

我发现合并数据很困难。我该怎么做?是否可以在不创建任何额外列的情况下实现它?

这是我的解决方案:

import datetime
import pandas as pd
df1 = pd.DataFrame(data=[
dict(ID=90, Date=datetime.date(2021, 2, 1)),
dict(ID=101, Date=datetime.date(2021, 1, 31)),
dict(ID=30, Date=datetime.date(2021, 12, 31)),
])

df2 = pd.DataFrame(data=[
{'ID': 90, '01/01/2022': 20, '02/01/2021': 14, '12/01/2021': 22},
{'ID': 101, '01/01/2022': 15, '02/01/2021': 10, '12/01/2021': 5},
{'ID': 30, '01/01/2022': 12, '02/01/2021': 9, '12/01/2021': 13},
])
df2_melted = pd.melt(df2, ['ID'], var_name='Date', value_name='val')
df2_melted['Date'] = pd.to_datetime(df2_melted['Date']).dt.date

df_merged = pd.merge(df1, df2_melted, on='ID')
df_merged['time_diff'] = (df_merged['Date_y'] - df_merged['Date_x']).dt.days
date_after_mask = df_merged['Date_y'] >= df_merged['Date_x']

dfg = df_merged.groupby('ID')['time_diff']
df_merged['min_diff'] = dfg.transform('min')
df_merged['max_diff'] = dfg.transform('max')
min_is_neg = df_merged['min_diff'] < 0
df_merged['min_diff'] = df_merged.min_diff.mask(min_is_neg, df_merged.max_diff)
valid_rows = df_merged['time_diff'] == df_merged['min_diff']
df_out = df_merged[valid_rows][['ID', 'Date_x', 'val']]
df_out.columns = ['ID', 'Date', 'Val']

输出:

ID        Date  Val
1   90  2021-02-01   14
4  101  2021-01-31   10
6   30  2021-12-31   12

最新更新