如何获取每行不同列的最后一个有效索引的值

时间:2019-11-08 09:53:56

标签: python pandas dataframe

我在熊猫里有下表。

  • 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'])

1 个答案:

答案 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