2016-07-29 7 views
2

Ich habe eine Panel-Daten, würde ich gerne die ersten (ein paar) Zeile (n), die NaN in jeder Gruppe enthalten. (Oder ein allgemeines Verfahren, das auf dem Index innerhalb der Gruppe und anderen Bedingungen reduzieren kann.)Pandas Tropfen die ersten paar Zeilen enthalten Nan in jeder Gruppe

df = pd.DataFrame(
{'ID': [10001, 10001, 10001, 10002, 10002, 10002, 10003, 10003, 10003, 10003], 
'PRICE': [None, 11.5, 14.31, 15.125, 14.44, None, None, None, None, 23.55], 
'date': [19920103, 19920106, 19920107, 19920108, 19920109, 19920110, 
      19920113, 19920114, 19920115, 19920116]}, 
index = range(1,11)) 

Die Daten würden wie folgt aussehen:

ID  PRICE date 
1 10001 NaN  19920103 
2 10001 11.500 19920106 
3 10001 14.310 19920107 
4 10002 15.125 19920108 
5 10002 14.440 19920109 
6 10002 NaN  19920110 
7 10003 NaN  19920113 
8 10003 NaN  19920114 
9 10003 NaN  19920115 
10 10003 23.550 19920116 

Ich mag würde Linie fallen 1 und 7, aber nicht 9 Linie, da die Leitung 9 nicht einer der ersten wenigen fehlenden Beobachtungen ist, habe ich versucht,

def mask_first_missing(x): 
    result = x.notnull() & x.rank()==1 
    return result 

mask = df.groupby(['ID'])['PRICE'].transform(mask_first_missing).astype(bool) 
print(df[mask]) 

aber es entfernt Reihe 1, 7 und 9, Reihe scheinbar 9 ist nicht die erste Beobachtung in der Gruppe 3,

Wenn ich dies tue

df[df.groupby('ID', as_index=False)['PRICE'].nth(0).notnull()] 

Dann wird der Index von groupby Objekt erstellt wird, nicht mit dem ursprünglichen Datenrahmen ausgerichtet

Könnte jemand mir dabei helfen? Danke

+1

Was ist die Regel, die definiert, welche NaN soll man behalten und fallen lassen? – piRSquared

Antwort

0

Thank Sie für Ihre Hilfe, aber ich denke, dass keine der Antworten zu meiner Aufgabe passt.

Ich habe selbst eine Lösung gefunden, indem ich eine Subindex-Spalte erstellt habe.

df = pd.DataFrame(
{'ID': [10001, 10001, 10001, 10001, 10002, 10002, 10002, 10003, 10003, 10003, 10003], 
'PRICE': [None, 11.5, None, 14.31, 15.125, 14.44, None, None, None, None, 23.55], 
'date': [19920103, 19920106, 19920107, 19920108, 19920109, 19920110, 
      19920113, 19920114, 19920115, 19920116, 19920122]}, 
index = range(1,12)) 

df.loc[:, 'subindex'] = df.groupby('ID').cumcount() 

Dann wird man

ID  PRICE date subindex 
1 10001 NaN  19920103 0 
2 10001 11.500 19920106 1 
3 10001 NaN  19920107 2 
4 10001 14.310 19920108 3 
5 10002 15.125 19920109 0 
6 10002 14.440 19920110 1 
7 10002 NaN  19920113 2 
8 10003 NaN  19920114 0 
9 10003 NaN  19920115 1 
10 10003 NaN  19920116 2 
11 10003 23.550 19920122 3 

erhalten Anstatt alles auf Basis groupby zu tun, jetzt kann ich die n-te Beobachtung der einzelnen Gruppen auf Spalte ‚Subindex‘ basiert wählen.

Nun, wenn ich die ersten beiden NaN Beobachtung von ‚Preis‘ jeder Gruppe fallen wollen, kann ich eine Maske erstellen

mask_first_few_nan = (df.loc[:, 'PRICE'].isnull()) & (df.loc[:, 'subindex'] <= 1) 
df[~mask_first_few_nan] 

Das Ergebnis ist

ID  PRICE date subindex 
2 10001 11.500 19920106 1 
3 10001 NaN  19920107 2 
4 10001 14.310 19920108 3 
5 10002 15.125 19920109 0 
6 10002 14.440 19920110 1 
7 10002 NaN  19920113 2 
10 10003 NaN  19920116 2 
11 10003 23.550 19920122 3 
1

Dies ist eine Möglichkeit, es zu tun:

notnull = df.PRICE.notnull() 
protected = df.index > df.PRICE.last_valid_index() 

df[notnull | protected] 

enter image description here

+0

Vielen Dank, aber ich habe ein Panel, ich möchte die ersten paar fehlende Beobachtungen jeder Gruppe fallen lassen. Die Methode hier funktioniert nicht. Vielleicht ist es meine Schuld, dass ich meine Frage klarer machen sollte – GrumpyJun

+0

Ich aktualisierte die Beispieldaten, ich versuchte die Methode, es funktioniert nicht gut – GrumpyJun

0

alternatve Ansatz mit benutzerdefinierten Ranking:

In [49]: %paste 
df[df.assign(x=np.where(pd.isnull(df.PRICE), 1, np.nan)) 
    .groupby('ID').x.cumsum().fillna(np.inf) > 1 
] 
## -- End pasted text -- 
Out[49]: 
     ID PRICE  date 
2 10001 11.500 19920106 
3 10001 14.310 19920107 
4 10002 15.125 19920108 
5 10002 14.440 19920109 
6 10002 14.120 19920110 
8 10003 16.500 19920114 
9 10003  NaN 19920115 

Erläuterung:

In [50]: df.assign(x=np.where(pd.isnull(df.PRICE), 1, np.nan)) 
Out[50]: 
     ID PRICE  date x 
1 10001  NaN 19920103 1.0 
2 10001 11.500 19920106 NaN 
3 10001 14.310 19920107 NaN 
4 10002 15.125 19920108 NaN 
5 10002 14.440 19920109 NaN 
6 10002 14.120 19920110 NaN 
7 10003  NaN 19920113 1.0 
8 10003 16.500 19920114 NaN 
9 10003  NaN 19920115 1.0 

In [51]: df.assign(x=np.where(pd.isnull(df.PRICE), 1, np.nan)).groupby('ID').x.cumsum().fillna(np.inf) 
Out[51]: 
1 1.000000 
2   inf 
3   inf 
4   inf 
5   inf 
6   inf 
7 1.000000 
8   inf 
9 2.000000 
Name: x, dtype: float64 

In [52]: df.assign(x=np.where(pd.isnull(df.PRICE), 1, np.nan)).groupby('ID').x.cumsum().fillna(np.inf) > 1 
Out[52]: 
1 False 
2  True 
3  True 
4  True 
5  True 
6  True 
7 False 
8  True 
9  True 
Name: x, dtype: bool 
Verwandte Themen