我有一个如下所示的df1
,df1
中的行是使用df2
的开始和结束日期选择的。如您所见,CaseName
df2
具有关联的 ID 号。
问题: 我想更新/更改/替换df1
中的CaseName
(由屏蔽日期时间戳w.r.t选择。df2
)CaseName
在df2
.
df
的原始形状是 (80000,15) 其余列是属性值。 使用开始和结束日期选择后
df1.shape = (29467,15)
Index CaseName TStamp
0 CASE_A 2016-05-19 00:00
1 CASE_A 2016-05-19 01:00
2 CASE_A 2016-05-19 02:00
3 CASE_A 2016-05-19 03:00
4 CASE_A 2016-05-19 04:00
5 CASE_B 2016-07-30 00:00
6 CASE_B 2016-07-30 02:00
7 CASE_B 2016-07-30 03:00
8 CASE_B 2016-07-30 04:00
9 CASE_B 2016-07-30 05:00
10 CASE_B 2016-07-30 06:00
df2.shape = (23,3)
Index CaseName Start End
0 CASE_A1 2016-05-19 2016-08-30
1 CASE_A2 2016-08-30 2017-01-06
2 CASE_A3 2017-01-06 2017-05-08
3 CASE_A4 2017-05-08 2017-08-01
4 CASE_A5 2017-08-01 2018-06-24
5 CASE_B1 2016-05-20 2016-07-30
6 CASE_B2 2016-07-30 2016-10-16
7 CASE_B3 2016-10-16 2017-01-14
8 CASE_B4 2017-01-14 2017-05-08
9 CASE_B5 2017-05-08 2017-08-03
10 CASE_B6 2017-08-03 2018-06-25
我试过了
- 在
df2
中逐行迭代。 - 使用
df2.Start
和df2.End
创建蒙版。 - 应用条件来分配值。
- 实际上
df1
有多种情况CASE_A,B,C,D。
#For single condition CASE_A
for index,row in df2.iterrows():
mask = (df1['TStamp'] > row['Start']) & (df1['TStamp'] <= row['End'])
temp_df = df1.loc[mask]
temp_df.loc[temp_df['CaseName'] == 'CASE_A','CaseName'] = row['CaseName ']
预期输出如下所示:
result_df1.shape = (29467,15)
Index CaseName TStamp
0 CASE_A1 2016-05-19 00:00
1 CASE_A1 2016-05-19 01:00
2 CASE_A1 2016-05-19 02:00
3 CASE_A1 2016-05-19 03:00
4 CASE_A1 2016-05-19 04:00
5 CASE_B2 2016-07-30 00:00
6 CASE_B2 2016-07-30 02:00
7 CASE_B2 2016-07-30 03:00
8 CASE_B2 2016-07-30 04:00
9 CASE_B2 2016-07-30 05:00
10 CASE_B2 2016-07-30 06:00
使用:
#convert columns to datetimes
df1['TStamp'] = pd.to_datetime(df1['TStamp'])
df2['Start'] = pd.to_datetime(df2['Start'])
df2['End'] = pd.to_datetime(df2['End'])
#remove last value in strings
df2['CaseName'] = df2['CaseName'].str[:-1]
#merge together
df = df1.merge(df2, on='CaseName')
#filter by condition and by columns names
mask = (df['TStamp'] > df['Start']) & (df['TStamp'] <= df['End'])
df = df.loc[mask, df1.columns]
print (df)
CaseName TStamp
5 CASE_A 2016-05-19 01:00:00
10 CASE_A 2016-05-19 02:00:00
15 CASE_A 2016-05-19 03:00:00
20 CASE_A 2016-05-19 04:00:00
25 CASE_B 2016-07-30 00:00:00
32 CASE_B 2016-07-30 02:00:00
38 CASE_B 2016-07-30 03:00:00
44 CASE_B 2016-07-30 04:00:00
50 CASE_B 2016-07-30 05:00:00
56 CASE_B 2016-07-30 06:00:00
假设所有日期列都已转换为日期时间。以下方法使用between
检查值是否属于某个范围
(df2.assign(CaseName1=df2.CaseName.str[:-1])
.join(df1.set_index('CaseName'), on='CaseName1')
.loc[lambda x:x.TStamp.between(x.Start,x.End),['CaseName','TStamp']])