这是我的数据帧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