我有两个数据帧,如下图df1和df2所示。
df1:
Date t_factor category
2020-02-01 5 A
2020-02-02 2 B
2020-02-03 1 C
2020-02-04 2 A
2020-02-05 3 B
2020-02-06 3 C
2020-02-07 3 A
2020-02-08 9 B
2020-02-09 1 C
2020-02-10 8 A
2020-02-11 3 B
2020-02-12 3 C
df2:
Date beta
2020-02-01 100
2020-02-02 230
2020-02-03 150
2020-02-04 100
2020-02-05 200
2020-02-06 180
2020-02-07 190
2020-02-08 290
从上面我想根据输入的日期范围将df1的t_factor列替换为df2的beta列。
功能可能是这样的。
def replace_column(df1, df2, start_date = `2020-02-03`, end_date = `2020-02-06`):
df1 = df1.copy()
df2 = df2.copy()
df1 = df1.sort_values(['Date'], ascending=True)
df2 = df2.sort_values(['Date'], ascending=True)
df1['t_factor'] = df1['beta'] # for that date range
return df1
预期输出:对于开始日期= 2020-02-03
和结束日期= 2020-02-06
df1:
Date t_factor category
2020-02-01 5 A
2020-02-02 2 B
2020-02-03 150 C
2020-02-04 100 A
2020-02-05 200 B
2020-02-06 180 C
2020-02-07 3 A
2020-02-08 9 B
2020-02-09 1 C
2020-02-10 8 A
2020-02-11 3 B
2020-02-12 3 C
注意:df2的数据较少,df2的最终日期为2020-02-08
。
if start_date = `2020-02-07` and end_date = `2020-02-11`.
然后预期输出:
Date t_factor category
2020-02-01 5 A
2020-02-02 2 B
2020-02-03 1 C
2020-02-04 2 A
2020-02-05 3 B
2020-02-06 3 C
2020-02-07 190 A
2020-02-08 290 B
2020-02-09 1 C
2020-02-10 8 A
2020-02-11 3 B
2020-02-12 3 C
print ('df2 dont have data after 2020-02-08')
答案 0 :(得分:1)
我的解决方案使用df.join
和df.loc
方法。
首先初始化数据。
df1 = pd.DataFrame({'Date' : ['2020-02-01', '2020-02-05', '2020-02-06', '2020-02-12'],'t_factor' : [5, 3, 3, 3]})
df2 = pd.DataFrame({'Date' : ['2020-02-05', '2020-02-06'],'beta' : [200, 180]})
然后将Date
设置为索引。
df1d = df1.set_index('Date')
df2d = df2.set_index('Date')
现在是关键步骤。
dfres=df1d.join(df2d)
dfres.loc[dfres['beta'].notnull(), 't_factor'] = dfres.loc[dfres['beta'].notnull()].beta
又一步匹配预期的输出。
output=dfres.drop(columns='beta')
答案 1 :(得分:1)
使用pd.to_datetime
将Date
类列转换为熊猫datetime
系列。
df1['Date'] = pd.to_datetime(df1['Date'])
df2['Date'] = pd.to_datetime(df2['Date'])
然后使用Series.between
并指定开始日期(left
)和结束日期(right
)创建布尔掩码m
,然后使用boolean indexing
并使用Series.map
将beta
的{{1}}值映射到df2
中的t_function
值。
df1
另一个想法,使用DataFrame.merge
:
m = df1['Date'].between('2020-02-03', '2020-02-06', inclusive=True)
df1.loc[m, 't_factor'] = df1['Date'].map(df2.set_index('Date')['beta']).fillna(df1['t_factor'])
结果:
df1 = df1.merge(df2, on='Date', how='left')
m = df1['Date'].between('2020-02-03', '2020-02-06', inclusive=True)
df1.loc[m, 't_factor'] = df1.pop('beta').fillna(df1['t_factor'])
函数,该函数包装了# start=2020-02-03, end=2020-02-06
Date t_factor category
0 2020-02-01 5.0 A
1 2020-02-02 2.0 B
2 2020-02-03 150.0 C
3 2020-02-04 100.0 A
4 2020-02-05 200.0 B
5 2020-02-06 180.0 C
6 2020-02-07 3.0 A
7 2020-02-08 9.0 B
8 2020-02-09 1.0 C
9 2020-02-10 8.0 A
10 2020-02-11 3.0 B
11 2020-02-12 3.0 C
# start=2020-02-07, end=2020-02-11.
Date t_factor category
0 2020-02-01 5.0 A
1 2020-02-02 2.0 B
2 2020-02-03 1.0 C
3 2020-02-04 2.0 A
4 2020-02-05 3.0 B
5 2020-02-06 3.0 C
6 2020-02-07 190.0 A
7 2020-02-08 290.0 B
8 2020-02-09 1.0 C
9 2020-02-10 8.0 A
10 2020-02-11 3.0 B
11 2020-02-12 3.0 C
方法merging
:
(Method 2)