2017-05-03 5 views
1

ich einen Datenrahmen haben wie diesePython Pandas: Erstellen Sie neue Spalte aus anderen Spalten, in denen Wert nicht null ist

---------------- 
RecID| A |B 
---------------- 
1 |NaN | x 
2 |y | NaN 
3 |z | NaN 
4 |NaN | a 
5 |NaN | b 

Und ich möchte eine neue Spalte erstellen, C, von A und B, so dass, wenn A ist null dann mit B füllen und wenn B null ist, dann füllen A:

---------------------- 
RecID|A |B |C 
---------------------- 
1 |NaN | x |x 
2 |y | NaN |y 
3 |z | NaN |z 
4 |NaN | a |a 
5 |NaN | b |b 

Schließlich ist es eine effiziente Möglichkeit, dies zu tun, wenn ich mehr als zwei Spalten aufweisen, zB Ich habe Spalten A-Z und möchte eine neue Spalte A1 aus den Spalten A-Z ähnlich wie oben erstellen?

+0

ich meine Antwort nur aktualisiert, um die allgemeine Lösung, nach der Sie gesucht haben. Sie haben jetzt über 15 Ruf. Fühlen Sie sich frei, irgendwelche Antworten zu bewerten, die Sie nützlich finden. – piRSquared

Antwort

4

Im Falle von mehreren Spalten, können Sie vorwärts füllen verwenden. In diesem Beispiel wird davon ausgegangen, dass Sie eine Kombination aus allen Spalten ‚A‘ bis ‚Z‘ aufbauen wollen:

df['AZ'] = df.loc[:,'A':'Z'].fillna(method='ffill',axis=1)['Z'] 

Diese Methode funktioniert für zwei Spalten, auch:

df['C'] = df.loc[:,'A':'B'].fillna(method='ffill',axis=1)['B'] 
#0 x 
#1 y 
#2 z 
#3 a 
#4 b 
+0

Wie funktioniert das, wenn die Spalten, die ich Werte aus der neuen Spalte ziehen möchte, nicht in Ordnung sind? – kflaw

6

pandas
lookup
Dies ist die verallgemeinerbare Lösung OP suchte und wird über eine beliebige Anzahl von Spalten arbeiten.

lookup = df.loc[:, 'A':'B'].notnull().idxmax(1) 
df.assign(A1=df.lookup(lookup.index, lookup.values)) 

    RecID A B A1 
0  1 NaN x x 
1  2 y NaN y 
2  3 z NaN z 
3  4 NaN a a 
4  5 NaN b b 

fillna

df.assign(C=df.A.fillna(df.B)) 

    RecID A B C 
0  1 NaN x x 
1  2 y NaN y 
2  3 z NaN z 
3  4 NaN a a 
4  5 NaN b b 

mask

df.assign(C=df.A.mask(df.A.isnull(), df.B)) 

    RecID A B C 
0  1 NaN x x 
1  2 y NaN y 
2  3 z NaN z 
3  4 NaN a a 
4  5 NaN b b 

combine_first

df.assign(C=df.A.combine_first(df.B)) 

    RecID A B C 
0  1 NaN x x 
1  2 y NaN y 
2  3 z NaN z 
3  4 NaN a a 
4  5 NaN b b 

numpy
np.where

df.assign(C=np.where(df.A.notnull(), df.A, df.B)) 

    RecID A B C 
0  1 NaN x x 
1  2 y NaN y 
2  3 z NaN z 
3  4 NaN a a 
4  5 NaN b b 
+0

Sind diese alle _exactly_ die gleiche Sache? Ich versuche zu verfolgen und sie sehen alle so aus, als würden sie sich auf dieselbe Weise verhalten (außerhalb dieses spezifischen Beispiels). – roganjosh

+1

@roganjosh Fast die gleiche Sache. 'fillna' geht davon aus, dass Sie bereits Nullen gefüllt haben. 'mask' erstellt Nullen und füllt sie im selben Methodenaufruf. 'combine_first' enthält auch neue Indizes aus dem übergebenen Argument. Es kommt vor, dass es sich um eine andere Spalte aus demselben Datenrahmen und daher um denselben Index handelt. – piRSquared

+0

geschätzt. Kombiniert mit Ihrem Kommentar, ist dies eine ausgezeichnete Ressource für mich :) – roganjosh

Verwandte Themen