2017-02-20 3 views
5

ich dies nur bemerkt haben:Pandas logische und Betreiber mit und ohne Klammern zu unterschiedlichen Ergebnissen

df[df.condition1 & df.condition2] 
df[(df.condition1) & (df.condition2)] 

Warum der Ausgang dieser beiden Linien unterscheiden?


ich nicht die genauen Daten gemeinsam nutzen können, aber ich versuche ich werde so detailliert wie möglich zu bieten:

df[df.col1 == False & df.col2.isnull()] # returns 33 rows and the rule `df.col2.isnull()` is not in effect 
df[(df.col1 == False) & (df.col2.isnull())] # returns 29 rows and both conditions are applied correctly 

Dank hier an @jezrael und @ayhan, was passiert ist, und lassen Sie mich das Beispiel von @jezael bereitgestellt verwenden:

df = pd.DataFrame({'col1':[True, False, False, False], 
        'col2':[4, np.nan, np.nan, 1]}) 

print (df) 
    col1 col2 
0 True 4.0 
1 False NaN 
2 False NaN 
3 False 1.0 

Wenn wir einen Blick auf Zeile 3:

col1 col2 
3 False 1.0 

und die Art, wie ich die Bedingung schrieb:

df.col1 == False & df.col2.isnull() # is equivalent to False == False & False 

Da die & Zeichen höhere Priorität hat als ==, ohne Klammern False == False & False ist Äquivalent:

False == (False & False) 
print(False == (False & False)) # prints True 

Mit Klammern:

print((False == False) & False) # prints False 

Ich denke, es ist ein wenig einfacher ist es, dieses Problem mit Zahlen zu verdeutlichen:

print(5 == 5 & 1) # prints False, because 5 & 1 returns 1 and 5==1 returns False 
print(5 == (5 & 1)) # prints False, same reason as above 
print((5 == 5) & 1) # prints 1, because 5 == 5 returns True, and True & 1 returns 1 

So Lektionen gelernt: immer Klammern hinzuzufügen !!!

Ich wünschte, ich kann die Antwort Punkte sowohl @jezrael und @ayhan gespalten :(

Antwort

9

Es gibt keinen Unterschied zwischen df[condition1 & condition2] und df[(condition1) & (condition2)] Der Unterschied ergibt sich, wenn Sie einen Ausdruck und den Bediener schreiben & Vorrang.

df = pd.DataFrame(np.random.randint(0, 10, size=(5, 3)), columns=list('abc'))  
df 
Out: 
    a b c 
0 5 0 3 
1 3 7 9 
2 3 5 2 
3 4 7 6 
4 8 8 1 

condition1 = df['a'] > 3 
condition2 = df['b'] < 5 

df[condition1 & condition2] 
Out: 
    a b c 
0 5 0 3 

df[(condition1) & (condition2)] 
Out: 
    a b c 
0 5 0 3 

Allerdings, wenn Sie es wie folgt eingeben erhalten Sie eine Fehlermeldung angezeigt:

df[df['a'] > 3 & df['b'] < 5] 
Traceback (most recent call last): 

    File "<ipython-input-7-9d4fd21246ca>", line 1, in <module> 
    df[df['a'] > 3 & df['b'] < 5] 

    File "/home/ayhan/anaconda3/lib/python3.5/site-packages/pandas/core/generic.py", line 892, in __nonzero__ 
    .format(self.__class__.__name__)) 

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Dies liegt daran, dass 3 & df['b'] zuerst ausgewertet wird (dies entspricht False & df.col2.isnull() in Ihrem Beispiel). Sie müssen also die Bedingungen in Klammern Gruppe:

df[(df['a'] > 3) & (df['b'] < 5)] 
Out[8]: 
    a b c 
0 5 0 3 
1

Sie haben Recht, es Unterschied ist, und ich denke, dass es ein Problem mit Priorität von Operatoren - überprüfen docs:

df = pd.DataFrame({'col1':[True, False, False, False], 
        'col2':[4, np.nan, np.nan, 1]}) 

print (df) 
    col1 col2 
0 True 4.0 
1 False NaN 
2 False NaN 
3 False 1.0 

# operator & precedence 
print (df[df.col1 == False & df.col2.isnull()]) 
    col1 col2 
1 False NaN 
2 False NaN 
3 False 1.0 

# operator == precedence bacause in brackets 
print (df[(df.col1 == False) & (df.col2.isnull())]) 
    col1 col2 
1 False NaN 
2 False NaN 

Es scheint, dass ich es gefunden in docs - 6.16. Operator Vorrang wo sehen & haben eine höhere Priorität als ==:

Operator        Description 

lambda         Lambda expression 
if – else        Conditional expression 
or          Boolean OR 
and          Boolean AND 
not x         Boolean NOT 
in, not in, is, is not,     Comparisons, including membership tests  
<, <=, >, >=, !=, ==     and identity tests 
|          Bitwise OR 
^          Bitwise XOR 
&          Bitwise AND 

(expressions...), [expressions...],  Binding or tuple display, list display,  
{key: value...}, {expressions...}  dictionary display, set display 
+0

So die Betreiber Priorität hat, bin ich immer noch verwirrt. – Cheng

+0

'Die folgende Tabelle fasst die Rangfolge der Operatoren in Python zusammen, von der niedrigsten Priorität (niedrigste Bindung) bis zur höchsten Priorität (am meisten bindend). 'so denke ich' & 'hat höhere Priorität als' == '. Bitte beachten Sie das aktualisierte OP – Cheng

Verwandte Themen