Pandas:groupby并获取第一行匹配条件的index

Pandas: groupby and get index of first row matching condition

我有一个pandasDataFramedf,按时间顺序排列。每行代表对网站的一次访问。

df 有一个名为 display 的列,表示特定页面在访问期间被显示的次数。此列由 0 或更大的整数填充。 df 也有一个 user 列。

我想知道每个用户在看到我感兴趣的关键业务页面之前访问该网站的次数。

要知道这一点,我需要一个用户索引 Series 填充如下:

df.groupby('user').display.apply(nvisits_before_display)

import numpy as np
def nvisits_before_display(x):
    try:
        return np.where(x > 0)[0].item(0) + 1
    except IndexError:
        return 0

这是什么意思?

  • x > 0,当应用于列display时,表示该页面已在给定访问
  • 中显示
  • np.where(<condition>)[0] returns 包含满足条件的索引(有序整数)位置的 numpy.ndarray
  • item(0)是取第一个位置,意思是第一次访问页面已经显示的地方
  • + 1代表设置值1给第一次访问该页面的用户
  • groupby('user')nvisits_before_display 函数应用于属于每个用户的行

我认为使用普通的 ol' argmax 更容易:

In [11]: df = pd.DataFrame([[1, 0], [1, 0], [1, 1], [2, 0], [2, 1]], columns=['user', 'display'])

In [12]: df
Out[12]:
   user  display
0     1        0
1     1        0
2     1        1
3     2        0
4     2        1

In [13]: df.groupby('user')['display'].apply(lambda x: np.argmax(x.values))
Out[13]:
user
1       2
2       1
Name: display, dtype: int64

不过,为了清楚起见(或者如果显示不是布尔值),我会定义一个新列:

In [21]: df['seen'] = df['display'] > 0

In [22]: df.groupby('user')['seen'].apply(lambda x: np.argmax(x.values))
Out[22]:
user
1       2
2       1
Name: seen, dtype: int64

注意:我的旧答案说 df.groupby('user')['display'].apply(np.argmax) 这不太正确,因为这给出了第一个 True index.