Pandas:groupby并获取第一行匹配条件的index
Pandas: groupby and get index of first row matching condition
我有一个pandasDataFrame
叫df
,按时间顺序排列。每行代表对网站的一次访问。
df
有一个名为 display
的列,表示特定页面在访问期间被显示的次数。此列由 0 或更大的整数填充。
df
也有一个 user
列。
我想知道每个用户在看到我感兴趣的关键业务页面之前访问该网站的次数。
要知道这一点,我需要一个用户索引 Series
填充如下:
- 0 如果用户从未显示该页面
- 否则,到第一行的行数(即访问次数),其中
display
非零(意思是用户第一次访问时看到的页面)
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.
我有一个pandasDataFrame
叫df
,按时间顺序排列。每行代表对网站的一次访问。
df
有一个名为 display
的列,表示特定页面在访问期间被显示的次数。此列由 0 或更大的整数填充。
df
也有一个 user
列。
我想知道每个用户在看到我感兴趣的关键业务页面之前访问该网站的次数。
要知道这一点,我需要一个用户索引 Series
填充如下:
- 0 如果用户从未显示该页面
- 否则,到第一行的行数(即访问次数),其中
display
非零(意思是用户第一次访问时看到的页面)
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.