TLDR; Pandalar içinde Mantıksal Operatörler vardır &
, |
ve ~
, ve parantez (...)
önemli!
Python var and
, or
ve not
mantıksal operatörler skalerler ile çalışmak üzere tasarlanmıştır. Bu yüzden Pandalar bu işlevin vektörize (element-wise) versiyonunu elde etmek için daha iyisini yapmak ve bitsel operatörleri geçersiz kılmak zorunda kaldı .
Python'da aşağıdakiler ( exp1
ve exp2
bir boole sonucunu değerlendiren ifadelerdir) ...
exp1 and exp2 # Logical AND
exp1 or exp2 # Logical OR
not exp1 # Logical NOT
... tercüme edilecek ...
exp1 & exp2 # Element-wise logical AND
exp1 | exp2 # Element-wise logical OR
~exp1 # Element-wise logical NOT
pandalar için.
Mantıksal işlem gerçekleştirme sürecinde bir ValueError
alırsanız, gruplama için parantez kullanmanız gerekir:
(exp1) op (exp2)
Örneğin,
(df['col1'] == x) & (df['col2'] == y)
Ve bunun gibi.
Boolean Dizinleme : Ortak bir işlem, verileri filtrelemek için mantıksal koşullar aracılığıyla boolean maskeleri hesaplamaktır. Pandalar üç operatör sağlar:&
mantıksal VE,|
mantıksal VEYA ve~
mantıksal DEĞİL için.
Aşağıdaki kurulumu düşünün:
np.random.seed(0)
df = pd.DataFrame(np.random.choice(10, (5, 3)), columns=list('ABC'))
df
A B C
0 5 0 3
1 3 7 9
2 3 5 2
3 4 7 6
4 8 8 1
Mantıksal VE
İçin df
yukarıda, A <5 ve B> 5. Bu ayrı ayrı her durum için maskeler bilgisayar ve bunları operatörü kullanılarak eklenmesiyle yapılır tüm satırları iade etmek istiyorum söylüyorlar.
Aşırı Yüklü Bitsel &
Operatör
Devam etmeden önce lütfen aşağıdaki dokümanların bu özel alıntısına dikkat edin:
Diğer bir yaygın işlem, verileri filtrelemek için boole vektörlerinin kullanılmasıdır. İşleçler: |
için or
, &
için and
ve ~
içindir not
. Bu parantez kullanarak gruplandırılması gerekir gibi bir ifade değerlendirecek varsayılan Python tarafından yana df.A > 2 & df.B < 3
olarak df.A > (2 &
df.B) < 3
istenen değerlendirme sırası iken, (df.A > 2) & (df.B <
3)
.
Yani, bu düşünceyle, bilge mantıksal VE bitsel operatör ile uygulanabilir &
:
df['A'] < 5
0 False
1 True
2 True
3 True
4 False
Name: A, dtype: bool
df['B'] > 5
0 False
1 True
2 False
3 True
4 True
Name: B, dtype: bool
(df['A'] < 5) & (df['B'] > 5)
0 False
1 True
2 False
3 True
4 False
dtype: bool
Ve sonraki filtreleme adımı basitçe,
df[(df['A'] < 5) & (df['B'] > 5)]
A B C
1 3 7 9
3 4 7 6
Parantez koşullu operatörler üzerinde yüksek önceliğe sahip bit operatörleri, varsayılan öncelik sırasını geçersiz kılmak için kullanılır <
ve >
. Python belgelerinde Operatör Önceliği bölümüne bakın .
Parantez kullanmazsanız, ifade yanlış değerlendirilir. Örneğin, yanlışlıkla
df['A'] < 5 & df['B'] > 5
Şu şekilde ayrıştırılır
df['A'] < (5 & df['B']) > 5
Hangi olur,
df['A'] < something_you_dont_want > 5
Bu da olur ( zincirleme operatör karşılaştırmasında python belgelerine bakın ),
(df['A'] < something_you_dont_want) and (something_you_dont_want > 5)
Hangi olur,
# Both operands are Series...
something_else_you_dont_want1 and something_else_you_dont_want2
Hangi atar
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Yani, bu hatayı yapma! 1
Parantez Gruplarından Kaçınmak
Düzeltme aslında oldukça basittir. Çoğu işleç DataFrames için karşılık gelen bir bağlı yönteme sahiptir. Tek tek maskeler koşullu işleçler yerine işlevler kullanılarak oluşturulmuşsa, değerlendirme sırasını belirtmek için artık ebeveynlere göre gruplandırmanıza gerek kalmayacaktır:
df['A'].lt(5)
0 True
1 True
2 True
3 True
4 False
Name: A, dtype: bool
df['B'].gt(5)
0 False
1 True
2 False
3 True
4 True
Name: B, dtype: bool
df['A'].lt(5) & df['B'].gt(5)
0 False
1 True
2 False
3 True
4 False
dtype: bool
Esnek Karşılaştırmalar bölümüne bakın . . Özetlemek gerekirse,
╒════╤════════════╤════════════╕
│ │ Operator │ Function │
╞════╪════════════╪════════════╡
│ 0 │ > │ gt │
├────┼────────────┼────────────┤
│ 1 │ >= │ ge │
├────┼────────────┼────────────┤
│ 2 │ < │ lt │
├────┼────────────┼────────────┤
│ 3 │ <= │ le │
├────┼────────────┼────────────┤
│ 4 │ == │ eq │
├────┼────────────┼────────────┤
│ 5 │ != │ ne │
╘════╧════════════╧════════════╛
Parantezlerden kaçınmak için başka bir seçenek de DataFrame.query
(veya eval
) kullanmaktır :
df.query('A < 5 and B > 5')
A B C
1 3 7 9
3 4 7 6
Ben var yoğun belgelenmiş query
ve eval
içinde pd.eval kullanarak pandalar Dinamik ifade değerlendirme () .
operator.and_
Bu işlemi işlevsel bir şekilde gerçekleştirmenizi sağlar. Dahili Series.__and__
olarak, bitsel operatöre karşılık gelen çağrılar .
import operator
operator.and_(df['A'] < 5, df['B'] > 5)
# Same as,
# (df['A'] < 5).__and__(df['B'] > 5)
0 False
1 True
2 False
3 True
4 False
dtype: bool
df[operator.and_(df['A'] < 5, df['B'] > 5)]
A B C
1 3 7 9
3 4 7 6
Genellikle buna ihtiyacınız olmaz, ancak bilmek faydalıdır.
Genelleme: np.logical_and
(ve logical_and.reduce
) Parantez gruplandırmasına ihtiyaç duymayan
başka bir alternatif kullanmak np.logical_and
:
np.logical_and(df['A'] < 5, df['B'] > 5)
0 False
1 True
2 False
3 True
4 False
Name: A, dtype: bool
df[np.logical_and(df['A'] < 5, df['B'] > 5)]
A B C
1 3 7 9
3 4 7 6
np.logical_and
bir ufunc (Evrensel İşlevler) ve çoğu ufunc'un bir reduce
yöntemi vardır. Bu logical_and
, AND için birden fazla masanız varsa genellemenin daha kolay olduğu anlamına gelir . Örneğin, AND maskelerine m1
ve m2
ile m3
birlikte &
,
m1 & m2 & m3
Ancak, daha kolay bir seçenek
np.logical_and.reduce([m1, m2, m3])
Bu güçlüdür, çünkü daha karmaşık bir mantıkla bunun üzerine inşa etmenizi sağlar (örneğin, bir liste kavrayışında dinamik olarak maskeler oluşturmak ve hepsini eklemek):
import operator
cols = ['A', 'B']
ops = [np.less, np.greater]
values = [5, 5]
m = np.logical_and.reduce([op(df[c], v) for op, c, v in zip(ops, cols, values)])
m
# array([False, True, False, True, False])
df[m]
A B C
1 3 7 9
3 4 7 6
1 - Biliyorum bu noktaya uyuyorum, ama lütfen bana katlan. Bu çok , çok yaygın bir başlangıç hatasıdır ve çok ayrıntılı bir şekilde açıklanmalıdır.
Mantıksal VEYA
İçin df
yukarıda, tüm satırları A == 3 veya B == 7 iade etmek istiyorum söylüyorlar.
Aşırı yüklenmiş Bitsel |
df['A'] == 3
0 False
1 True
2 True
3 False
4 False
Name: A, dtype: bool
df['B'] == 7
0 False
1 True
2 False
3 True
4 False
Name: B, dtype: bool
(df['A'] == 3) | (df['B'] == 7)
0 False
1 True
2 True
3 True
4 False
dtype: bool
df[(df['A'] == 3) | (df['B'] == 7)]
A B C
1 3 7 9
2 3 5 2
3 4 7 6
Henüz yapmadıysanız, lütfen yukarıdaki Mantıksal VE bölümünü de okuyun , tüm uyarılar burada geçerlidir.
Alternatif olarak, bu işlem aşağıdakilerle belirtilebilir
df[df['A'].eq(3) | df['B'].eq(7)]
A B C
1 3 7 9
2 3 5 2
3 4 7 6
operator.or_
Series.__or__
Kaputun altında
aramalar .
operator.or_(df['A'] == 3, df['B'] == 7)
# Same as,
# (df['A'] == 3).__or__(df['B'] == 7)
0 False
1 True
2 True
3 True
4 False
dtype: bool
df[operator.or_(df['A'] == 3, df['B'] == 7)]
A B C
1 3 7 9
2 3 5 2
3 4 7 6
np.logical_or
İki koşul için logical_or
şunları kullanın :
np.logical_or(df['A'] == 3, df['B'] == 7)
0 False
1 True
2 True
3 True
4 False
Name: A, dtype: bool
df[np.logical_or(df['A'] == 3, df['B'] == 7)]
A B C
1 3 7 9
2 3 5 2
3 4 7 6
Birden çok maske için logical_or.reduce
şunları kullanın :
np.logical_or.reduce([df['A'] == 3, df['B'] == 7])
# array([False, True, True, True, False])
df[np.logical_or.reduce([df['A'] == 3, df['B'] == 7])]
A B C
1 3 7 9
2 3 5 2
3 4 7 6
Mantıksal DEĞİL
Bir maske verildi, örneğin
mask = pd.Series([True, True, False])
Her bir boolean değerini tersine çevirmeniz gerekiyorsa (sonuçta bu şekilde olur [False, False, True]
), aşağıdaki yöntemlerden herhangi birini kullanabilirsiniz.
Bitsel ~
~mask
0 False
1 False
2 True
dtype: bool
Yine, ifadelerin parantez içine alınması gerekir.
~(df['A'] == 3)
0 True
1 False
2 False
3 True
4 True
Name: A, dtype: bool
Bu dahili olarak
mask.__invert__()
0 False
1 False
2 True
dtype: bool
Ama doğrudan kullanmayın.
operator.inv
Dahili __invert__
olarak Seriyi arar .
operator.inv(mask)
0 False
1 False
2 True
dtype: bool
np.logical_not
Bu numpy çeşididir.
np.logical_not(mask)
0 False
1 False
2 True
dtype: bool
Not, np.logical_and
yerine np.bitwise_and
, logical_or
ile bitwise_or
ve logical_not
ile ikame edilebilir invert
.