2016-12-08 4 views
0

Es gibt drei Spalten in meinem vorhandenen Datenrahmen df: A, B, CPython, neue col Anlage auf vorhandene cols

Ich möchte eine andere Spalte D auf A, B, C

Die Basis hinzufügen Logik ist:

if (A == "a"): 
    D = "a" 
elif (A == "b") and (B in ["B", "C"]): 
    D = "A" 
elif (C == "c"): 
    D = "c" 
Note: the value of D can be NaN if all conditions are not satisfied. 

Gibt es elegante und kompakte Möglichkeiten zum Hinzufügen dieser Spalte?

+1

Mögliche Duplikate von [Pandas erstellen neue Spalte basierend auf Werten aus anderen Spalten] (http://stackoverflow.com/questions/26886653/pandas-create-new-column-based-on-values-from-other-columns) – lucasnadalutti

Antwort

4

A verschachtelt, wo der schnellste

sein sollte
np.where(df.A == 'a', 'a', 
     np.where((df.A == 'b') & (df.B.isin(['B','C'])), 'A', 
     np.where(df.C == 'c', 'c', np.nan))) 

Speed ​​Test

# create 100,000 rows of random data 
df = pd.DataFrame({'A':np.random.choice(['a','b','c','A','B','C'], 100000, True), 
       'B':np.random.choice(['a','b','c','A','B','C'], 100000, True), 
       'C':np.random.choice(['a','b','c','A','B','C'], 100000, True)}) 

%%timeit 
np.where(df.A == 'a', 'a', 
    np.where((df.A == 'b') & (df.B.isin(['B','C'])), 'A', 
    np.where(df.C == 'c', 'c', np.nan))) 

10 Schlaufen, am besten von 3: 33,4 ms pro Schleife

def my_logic(x): 
    if x[0] == 'a': 
     return 'a' 
    elif x[0] == 'b' and x[1] in ('B', 'C'): 
     return 'A' 
    elif x[2] == 'c': 
     return 'c' 
    return '' 

%%timeit 
df[['A', 'B', 'C']].apply(my_logic, axis=1) 

1 Schlaufen , Bestes von 3: 5,87 s pro Schleife

Verschachtelt wo ist 175 Mal schneller als apply - die Methode des letzten Ausweges.

0

Ich denke, dies ist die am besten lesbare Methode, obwohl immer noch etwas kompakt.

def my_logic(x): 
    if x[0] == 'a': 
     return 'a' 
    elif x[0] == 'b' and x[1] in ('B', 'C'): 
     return 'A' 
    elif x[2] == 'c': 
     return 'c' 
    return '' 

df['D'] = df[['A', 'B', 'C']].apply(my_logic, axis=1) 
+0

'apply' sollte eine Methode des letzten Ausweges sein, da es für nur gerade mittelgroße Datenrahmen unglaublich langsam sein kann, da es nicht vektorisiert ist. Vielleicht ein Teil des Problems ist die Vielzahl von Funktionen in R. Pandas ist wahrscheinlich am besten gelernt, ohne zu wissen, anwenden. –

+0

@TedPetrou Schöne Arbeit mit dem Geschwindigkeitstest in Ihrem Kommentar! Ich glaube, dass apply ist ein ausgezeichnetes Pandas-Tool für Anfänger, weil es Code in einem lesbareren Format geschrieben werden kann. – AlexG

0

Dies wäre schneller als die if/elif-Lösung und weniger Zeilen. Es ist jedoch wohl nicht so gut lesbar.

df.loc[df.A=="a", "D") = "a" 
df.loc[(df.A=="b") & df.B.isin("B", "C"), "D") = "A" 
df.loc[(df.C=="c") & ~df.A.isin("a", "A"), "D"] = "c" 
df.loc[~df.D.isin("a", "A", "c"), "D"] = np.nan 
Verwandte Themen