2017-09-23 7 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'})] 

は、最初の購入は、データフレームから、各ユーザのために起こる前に起こるすべての行を選択する方法はありますか?この例では、所望の出力が使用groupby

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

であり、ユーザがいくつかのアイテムを購入した行の上にあるすべての行を見つけます。次に、マスクを使用してインデックスを作成します。

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を使用してに変換します。、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 
関連する問題