2017-10-20 1 views
2

Lets sagen, dass ich einen Datenrahmen haben, die eine Menge von fehlenden Daten hat:Pandas halten die vollständigste Reihen

df = pd.DataFrame({'id': ['a','a','b','b','b','c','d','e','e','e'], 
        'q1': [1,1,np.NaN,np.NaN,0,np.NaN,1,np.NaN,1,0], 
        'q2': ['low',np.NaN,np.NaN,'high','low','high','high',np.NaN,np.NaN,'low'], 
        'q3': [np.NaN,1,np.NaN,1,0,0,1,0,np.NaN,np.NaN] 
        }) 

die wie folgt aussieht:

id q1 q2 q3 
0 a 1.0 low NaN 
1 a 1.0 NaN 1.0 
2 b NaN NaN NaN 
3 b NaN high 1.0 
4 b 0.0 low 0.0 
5 c NaN high 0.0 
6 d 1.0 high 1.0 
7 e NaN NaN 0.0 
8 e 1.0 NaN NaN 
9 e 0.0 low NaN 

ich einen neuen Datenrahmen erstellen möchten, dass enthält nur 1 Zeile von jedem id, aber diese Zeile ist die vollständigste (am wenigsten Instanzen von NaN), aber wenn sie gleich vollständig sind, dann das erste Auftreten in der aktuellen Sortierreihenfolge

Ide al-Ausgang ist ein neuer Datenrahmen:

id q1 q2 q3 
0 a 1.0 low NaN 
1 b 0.0 low 0.0 
2 c NaN high 0.0 
3 d 1.0 high 1.0 
4 e 0.0 low NaN 

ich die Anzahl der NA in jeder Reihe zähle df.isnull().sum(axis=1) verwenden, aber ich bin mir nicht sicher, wie das verwenden, um dann mit der kleinsten Summe die Zeile auswählen, vor allem, wenn es sind mehr als 2 Einträge für eine id

Antwort

2

Sie könnten eine Ersatzspalte verwenden, um basierend auf Zählungen zu sortieren und mit einer groupby zu filtern.

df = df.assign(count=df.isnull().sum(1))\ 
     .sort_values(['id', 'count'])\ 
     .groupby('id', as_index=0).head(1)\ 
     .drop('count', 1) 

print(df) 
    id q1 q2 q3 
0 a 1.0 low NaN 
4 b 0.0 low 0.0 
5 c NaN high 0.0 
6 d 1.0 high 1.0 
9 e 0.0 low NaN 
+0

ah interessant. Wenn 2 Zeilen den gleichen "Count" haben, wie wählt man dann welche Zeile behalten? – Simon

+0

@Simon sollte es das erste Element sein, unter der Annahme, dass sort_values ​​wie erwartet funktioniert. –

2

Dies ist, was ich tun werde, drop_duplicates, können Sie die Notnullvalue.drop('Notnullvalue',1) durch Klage gegen fallen kann

df['Notnullvalue']=df.isnull().sum(1) 
df.sort_values(['id','Notnullvalue']).drop_duplicates(['id'],keep='first') 
Out[15]: 
    id q1 q2 q3 Notnullvalue 
0 a 1.0 low NaN    1 
4 b 0.0 low 0.0    0 
5 c NaN high 0.0    1 
6 d 1.0 high 1.0    0 
9 e 0.0 low NaN    1 
0

Inspiriert von @COLDSPEED, habe ich eine solche Lösung. Hinweis na_position='last' ist die Standardeinstellung in sort_values.

df.sort_values(by=['q1','q2','q3'], na_position='last').groupby('id').head(1).sort_index()