2017-05-05 70 views
7

我有一個看起來像這樣的數據幀:熊貓:過濾組由多個條件組成?

df = pd.DataFrame([ 
    {'id': 123, 'date': '2016-01-01', 'is_local': True }, 
    {'id': 123, 'date': '2017-01-01', 'is_local': False }, 
    {'id': 124, 'date': '2016-01-01', 'is_local': True }, 
    {'id': 124, 'date': '2017-01-01', 'is_local': True } 
]) 
df.date = df.date.astype('datetime64[ns]') 

我想要得到這is_local是在2016年開始真正的所有ID的列表,但假以2017年我開始」 VE通過分組開始由ID:

gp = df.groupby('id') 

然後,我已經試過這只是由這些條件的第二(作爲入門的方式)來過濾,但它返回所有組:

gp.apply(lambda x: ~x.is_local & (x.date > '2016-12-31')) 

如何以我需要的方式過濾?

回答

7
d1 = df.set_index(['id', 'date']).is_local.unstack() 
d1.index[d1['2016-01-01'] & ~d1['2017-01-01']].tolist() 

[123] 
3

這樣做的另一個方法是通過pivoting

In [24]: ids_by_dates = df.pivot(index='id', columns='date',values='is_local') 

In [25]: ids_by_dates['2016-01-01'] & ~ids_by_dates['2017-01-01'] 
Out[25]: 
id 
123  True 
124 False 
3

您可以嘗試使用從日期時間庫datetime模塊,並通過多個條件爲數據幀

from datetime import datetime 
df = pd.DataFrame([ 
    {'id': 123, 'date': '2016-01-01', 'is_local': True }, 
    {'id': 123, 'date': '2017-01-01', 'is_local': False }, 
    {'id': 124, 'date': '2016-01-01', 'is_local': True }, 
    {'id': 124, 'date': '2017-01-01', 'is_local': True } 
]) 
df.date = df.date.astype('datetime64[ns]') 

使用多個條件用於切出所需的數據幀

a = df[(df.is_local==True) & (df.date<datetime(2016,12,31) & (df.date>datetime(2015,12,31))] 
b = df[(df.is_local==False) & (df.date<datetime(2017,12,31)) & (df.date>datetime(2016,12,31))] 

使用熊貓拼接後

final_df = pd.concat((a,b)) 

將輸出你行1和2

date  id is_local 
2 2016-01-01 124 True 
1 2017-01-01 123 False 

在單行如下

final_df = pd.concat((df[(df.is_local==True) & (df.date<datetime(2016,12,31) & (df.date>datetime(2015,12,31))], df[(df.is_local==False) & (df.date<datetime(2017,12,31)) & (df.date>datetime(2016,12,31))])) 
+0

謝謝 - 我將如何使用它來獲取所有2016年初的'has_local'爲True且2017年爲False的行? – Richard

+0

我只能想到一個骯髒的解決方案,你添加多個條件,並將它們連接到另一個。相應地編輯我的答案。 – Mechanic

+0

我還編輯了我的答案與另一個條件分別限制到2016年和2017年 – Mechanic