根据熊猫中的特定条件,将df的列替换为另一个df的另一个列

时间:2020-07-15 08:59:09

标签: python-3.x pandas dataframe

我有两个数据帧,如下图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')

2 个答案:

答案 0 :(得分:1)

我的解决方案使用df.joindf.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_datetimeDate类列转换为熊猫datetime系列。

df1['Date'] = pd.to_datetime(df1['Date'])
df2['Date'] = pd.to_datetime(df2['Date'])

然后使用Series.between并指定开始日期(left)和结束日期(right)创建布尔掩码m,然后使用boolean indexing并使用Series.mapbeta的{​​{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)