2017-05-05 34 views
7

Tôi có một khung dữ liệu mà trông như thế này:gấu trúc: nhóm lọc theo nhiều điều kiện?

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]') 

Tôi muốn có được một danh sách tất cả các ID mà is_local là Đúng vào lúc bắt đầu của năm 2016, nhưng False vào đầu năm 2017. Tôi' đã bắt đầu theo nhóm bằng ID:

gp = df.groupby('id') 

Sau đó, tôi đã cố gắng này chỉ để lọc theo thứ hai của những điều kiện này (như một cách để bắt đầu), nhưng nó trả lại tất cả các nhóm:

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

Làm cách nào để lọc theo cách tôi cần?

Trả lời

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

[123] 
3

Một cách khác để làm điều này là thông qua 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

Bạn có thể thử bằng cách sử dụng mô-đun datetime từ thư viện datetime và vượt qua nhiều điều kiện để dataframe

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]') 

Sử dụng nhiều điều kiện để cắt ra khung dữ liệu bắt buộc

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))] 

Sử dụng gấu trúc nối sau

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

chí đầu ra bạn hàng 1 và 2

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

Trong dòng đơn như sau

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

Cảm ơn - làm thế nào tôi sẽ sử dụng này để có được tất cả hàng mà 'has_local' là True vào đầu năm 2016 và False vào năm 2017? – Richard

+0

Tôi chỉ có thể nghĩ ra một giải pháp bẩn mà u thêm nhiều điều kiện và concat chúng togeother .. Edited câu trả lời của tôi cho phù hợp .. – Mechanic

+0

Tôi cũng đã sửa câu trả lời của tôi với một điều kiện khác để hạn chế năm 2016 và 2017 tương ứng – Mechanic

Các vấn đề liên quan