2017-09-23 31 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