2017-05-05 5 views
7

Ich habe einen Datenrahmen, der wie folgt aussieht:Pandas: Filtergruppe durch mehrere Bedingungen?

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

Ich möchte eine Liste aller IDs erhalten, für die is_local zu Beginn 2016 wahr war, aber falsch zu Beginn von 2017. I‘ habe durch Gruppierung von ID gestartet:

gp = df.groupby('id') 

Dann habe ich versucht, dies durch die zweite diese Bedingungen zu filtern, dass nur (als eine Möglichkeit, die ersten Schritte), aber es ist die Rückkehr aller Gruppen:

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

Wie kann ich so filtern, wie ich es brauche?

Antwort

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

[123] 
3

Ein anderer Weg, dies zu tun, ist durch 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

Sie können versuchen, das Datetime-Modul von Datetime-Bibliothek und mehrere Bedingungen für die Datenrahmen

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

Verwenden Sie mehrere Bedingungen passieren zum Herausschneiden des erforderlichen Datenrahmens

später 210

Verwenden Pandas verketten

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

ausgeben wird Sie die Zeilen 1 und 2

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

In einzelnen Zeile wie folgt

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

Dank - wie würde ich diese verwenden, um alle zu erhalten Zeilen, für die 'has_local' zu Beginn des Jahres 2016 True und 2017 False ist? – Richard

+0

Ich konnte nur an eine schmutzige Lösung denken, wo Sie mehrere Bedingungen addieren und sie zusammenfügen. Bearbeitete meine Antwort dementsprechend .. – Mechanic

+0

Ich redigierte auch meine Antwort mit einer anderen Bedingung, um das Jahr bis 2016 und 2017 einzuschränken – Mechanic

Verwandte Themen