我在熊猫里有下表。
view_time
:用户观看广告的时间click_time
:用户点击广告的时间(如果被点击)ad_id
:广告标识符>>> df
view_time click_time username ad_id
250 07:00 07:05 a abc
251 07:10 a def
252 07:20 07:35 a ghi
253 07:30 07:41 a jkl
254 07:40 a mno
255 07:50 a pqr
我想添加一列,以显示每个时间点(view_time
)上最后点击的广告。
请注意,click_time
的值可能大于下一个view_time
的值。
last_clicked_ad
:截至view_time
的最后点击的广告 view_time click_time username ad_id last_clicked_ad
250 07:00 07:05 a abc
251 07:10 a def abc
252 07:20 07:35 a ghi abc
253 07:30 07:41 a jkl abc
254 07:40 a mno ghi
255 07:50 a pqr jkl
我尝试过这样的事情:
>>> i = df[['click_time']].apply(pd.Series.last_valid_index)
>>> df.loc[i, 'ad_id']
253 jkl
Name: ad_id, dtype: object
这给我最后一行的ad_id
值,其中click_time
是非空值。
但是,我想在每个时间点(view_time
)而不是整个表中使用此逻辑。
重现简化示例:
>>> df = pd.DataFrame({'view_time': ['07:00','07:10','07:20','07:30','07:40','07:50'],
'click_time': ['07:05', '', '07:35', '07:41', '', ''],
'username': ['a','a','a','a','a','a'],
'ad_id': ['abc', 'def','ghi','jkl','mno','pqr']
})
>>> df.index += 250
>>> df['view_time'] = pd.to_datetime(df['view_time'])
>>> df['click_time'] = pd.to_datetime(df['click_time'])
答案 0 :(得分:1)
使用merge_asof
:
df2 = (df[['click_time','username', 'ad_id']]
.dropna(subset=['click_time'])
.rename(columns={'ad_id':'last_clicked_ad', 'click_time':'new_time'}))
df = (pd.merge_asof(df, df2, left_on='view_time', right_on='new_time', by='username')
.drop('new_time', 1))
print (df)
view_time click_time username ad_id last_clicked_ad
0 2019-11-08 07:00:00 2019-11-08 07:05:00 a abc NaN
1 2019-11-08 07:10:00 NaT a def abc
2 2019-11-08 07:20:00 2019-11-08 07:35:00 a ghi abc
3 2019-11-08 07:30:00 2019-11-08 07:41:00 a jkl abc
4 2019-11-08 07:40:00 NaT a mno ghi
5 2019-11-08 07:50:00 NaT a pqr jkl