2017-09-23 32 views
3

如何选择在列中的某个值首次出现之前的行?在熊猫数据框的特定条目之前选择所有行

我有记录如下用户活动数据集及其时间戳:

df = pd.DataFrame([{'user_id':1, 'date':'2017-09-01', 'activity':'Open'}, 
        {'user_id':1, 'date':'2017-09-02', 'activity':'Open'} 
        {'user_id':1, 'date':'2017-09-03', 'activity':'Open'} 
        {'user_id':1, 'date':'2017-09-04', 'activity':'Click'} 
        {'user_id':1, 'date':'2017-09-05', 'activity':'Purchase'} 
        {'user_id':1, 'date':'2017-09-06', 'activity':'Open'} 
        {'user_id':1, 'date':'2017-09-07', 'activity':'Open'} 
        {'user_id':2, 'date':'2017-09-04', 'activity':'Open'} 
        {'user_id':2, 'date':'2017-09-06', 'activity':'Purchase'})] 

有没有一种方法来选择所有首次购买发生从数据帧中的每个用户在此之前发生的行?在这个例子中,欲望输出将是

df = pd.DataFrame([{'user_id':1, 'date':'2017-09-01', 'activity':'Open'}, 
        {'user_id':1, 'date':'2017-09-02', 'activity':'Open'} 
        {'user_id':1, 'date':'2017-09-03', 'activity':'Open'} 
        {'user_id':1, 'date':'2017-09-04', 'activity':'Click'} 
        {'user_id':2, 'date':'2017-09-04', 'activity':'Open'})] 

回答

3

可避免与明确

In [2862]: df[df['activity'].eq('Purchase').groupby(df['user_id']).cumsum().eq(0)] 
Out[2862]: 
    activity  date user_id 
0  Open 2017-09-01  1 
1  Open 2017-09-02  1 
2  Open 2017-09-03  1 
3 Click 2017-09-04  1 
7  Open 2017-09-04  2 
申请
3

使用groupby,发现是在其中一个用户购买了一些商品的行以上的所有行。然后,使用掩码进行索引。

df 
    activity  date user_id 
0  Open 2017-09-01  1 
1  Open 2017-09-02  1 
2  Open 2017-09-03  1 
3  Click 2017-09-04  1 
4 Purchase 2017-09-05  1 
5  Open 2017-09-06  1 
6  Open 2017-09-07  1 
7  Open 2017-09-04  2 
8 Purchase 2017-09-06  2 

m = df.groupby('user_id').activity\ 
     .apply(lambda x: (x == 'Purchase').cumsum()) == 0 
df[m] 

    activity  date user_id 
0  Open 2017-09-01  1 
1  Open 2017-09-02  1 
2  Open 2017-09-03  1 
3 Click 2017-09-04  1 
7  Open 2017-09-04  2 

如果实际数据未排序喜欢它是在这里,你可以使用df.sort_values,并确保它是:


df = df.sort_values(['user_id', 'date']) 
1

使用groupbymaskDataFrameGroupBy.cumsum转换为bool,通过boolean indexing反转条件和过滤器:

#if necessary 
#df = df.sort_values(['user_id', 'date']) 
df = df[~df['activity'].eq('Purchase').groupby(df['user_id']).cumsum().astype(bool)] 
print (df) 
    user_id  date activity 
0  1 2017-09-01  Open 
1  1 2017-09-02  Open 
2  1 2017-09-03  Open 
3  1 2017-09-04 Click 
7  2 2017-09-04  Open 

详情:

print (~df['activity'].eq('Purchase').groupby(df['user_id']).cumsum().astype(bool)) 
0  True 
1  True 
2  True 
3  True 
4 False 
5 False 
6 False 
7  True 
8 False 
Name: activity, dtype: bool