2016-05-17 16 views
0

Ich habe gruppierte Datenrahmen und ich möchte Werte in jeder Gruppe abhängig von diesen Werten filtern.Filter in Gruppen Pandas

Ich habe versucht:

figure_cols = list("ABC") 

def get_threshold_for_IV(gr_vals): 
    return (gr_vals[figure_cols].max())/(gr_vals["A"].count()) 

def filter_IV(group): 
    A_tr, B_tr, C_tr = get_threshold_for_IV(group) 
    return group[(group.A >= A_tr) & (group.B >= B_tr) & (group.C >= C_tr)] 

# 1 attempt 
grouped.apply(filter_IV) 

# 2 attempt 
for name, group in grouped: 
    A_tr, B_tr, C_tr = get_threshold_for_IV(group) 
    group = group[(group.A < A_tr) & (group.B < B_tr) & (group.C < C_tr)] 

Aber nichts funktioniert. Daten werden nicht geändert. Meine Funktionen funktionieren gut. Wenn ich print in Zyklus einfüge, kann ich gefiltertes Ergebnis sehen.

Andere, was ich sagen soll, dass ich gruppierte Objekt nach Filteroperation haben will weitere Manipulationen zu tun

ich docs gelesen habe, aber es sieht aus wie ich blind bin. Kann jemand helfen?

EDIT

Added Selbst Beispiel enthalten:

import numpy as np 
import pandas as pd 

df = pd.DataFrame({'gr' : ['foo', 'bar', 'foo', 'bar', 
         'foo', 'bar', 'foo', 'foo'], 
        'A' : np.arange(8), 
        'B' : np.random.randn(8), 
        'C' : np.random.randn(8)}) 

def filter_gt_3(group): 
    return group[group.A < 3] 

grouped = df.groupby('gr') 
for name, group in grouped: 
    print 'group name: %s' % name 
    print group 
    group = filter_gt_3(group) 
    print "\nfiltered" 
    print group 


print '\n----------\n' 
print 'Nothing filtered:\n' 
for name, group in grouped: 
    print 'group name: %s' % name 
    print group 

Ausgabe

group name: bar 
    A   B   C gr 
1 1 1.486028 -0.382597 bar 
3 3 -0.501757 -0.771807 bar 
5 5 -0.836930 -1.514824 bar 

filtered 
    A   B   C gr 
1 1 1.486028 -0.382597 bar 

group name: foo 
    A   B   C gr 
0 0 0.678104 -0.940245 foo 
2 2 1.539903 1.460493 foo 
4 4 -0.033421 -1.078566 foo 
6 6 1.146298 0.039721 foo 
7 7 1.095707 -1.032275 foo 

filtered 
    A   B   C gr 
0 0 0.678104 -0.940245 foo 
2 2 1.539903 1.460493 foo 

---------- 

Nothing filtered: 

group name: bar 
    A   B   C gr 
1 1 1.486028 -0.382597 bar 
3 3 -0.501757 -0.771807 bar 
5 5 -0.836930 -1.514824 bar 
group name: foo 
    A   B   C gr 
0 0 0.678104 -0.940245 foo 
2 2 1.539903 1.460493 foo 
4 4 -0.033421 -1.078566 foo 
6 6 1.146298 0.039721 foo 
7 7 1.095707 -1.032275 foo 
+0

Können Sie ein eigenständiges, ausführbares Beispiel bereitstellen, das das Problem veranschaulicht? – BrenBarn

+0

@BrenBarn Ich habe Beispiel –

Antwort

1

group = filter_gt_3(group) Doing die ursprünglichen Daten nicht ändern. Es ordnet die gefilterten Daten nur einer lokalen Variablen namens group zu. Genauso ändert nichts, wenn Sie nur (wie in Ihrem ersten Beispiel) aufrufen. Wenn Sie mit den gefilterten Daten etwas unternehmen möchten, müssen Sie den Wert von diesen Operationen zurückgegeben.

Wenn Sie die gefilterten Daten erhalten möchten, tun Sie etwas wie

new_data = df.groupby('gr').apply(filter_gt_3) 

Beachten Sie, dass dies auch nicht die Originaldaten ändern: eine Dataframe neue erstellt und weist sie new_data. Sie können es zurück zum ursprünglichen Namen zuweisen, wenn Sie möchten (z. B. df = df.groupby...)

+0

hinzugefügt Ja, das verstehe ich. Um andere Manipulationen mit denselben Gruppen durchzuführen, sollte ich wieder "gruppieren"? –

+0

@ re-gor: Ja. (Oder Sie können eine Funktion schreiben, die alle gewünschten Manipulationen gleichzeitig ausführt.) – BrenBarn

+0

danke, manchmal sieht Pandas für mich nicht naheliegend aus. –

Verwandte Themen