ตัวดำเนินการเชิงตรรกะสำหรับการทำดัชนีบูลีนใน Pandas


154

ฉันทำงานกับดัชนีบูลีนในนุ่น คำถามคือทำไมคำสั่ง:

a[(a['some_column']==some_number) & (a['some_other_column']==some_other_number)]

ทำงานได้ดีในขณะที่

a[(a['some_column']==some_number) and (a['some_other_column']==some_other_number)]

ออกจากข้อผิดพลาดหรือไม่

ตัวอย่าง:

a=pd.DataFrame({'x':[1,1],'y':[10,20]})

In: a[(a['x']==1)&(a['y']==10)]
Out:    x   y
     0  1  10

In: a[(a['x']==1) and (a['y']==10)]
Out: ValueError: The truth value of an array with more than one element is ambiguous.     Use a.any() or a.all()

6
นี่เป็นเพราะอาร์เรย์ numpy และ pandas ซีรีส์ใช้ตัวดำเนินการระดับบิตมากกว่าตรรกะในขณะที่คุณกำลังเปรียบเทียบทุกองค์ประกอบในอาร์เรย์ / อนุกรมกับอีก ดังนั้นจึงไม่สมเหตุสมผลที่จะใช้ตัวดำเนินการเชิงตรรกะในสถานการณ์นี้ ดูที่เกี่ยวข้อง: stackoverflow.com/questions/8632033/…
EdChum

9
and != &ในหลาม andผู้ประกอบการในหลามไม่สามารถแทนที่ในขณะที่&ผู้ประกอบการ ( __and__) สามารถ ดังนั้นทางเลือกในการใช้งานของ&numpy และ pandas
Steven Rumbalski

คำตอบ:


209

เมื่อคุณพูด

(a['x']==1) and (a['y']==10)

คุณกำลังขอให้ Python แปลง(a['x']==1)และ(a['y']==10)ค่าบูลีนโดยปริยาย

อาร์เรย์ NumPy (ความยาวมากกว่า 1) และ Pandas เช่นซีรี่ส์ไม่มีค่าบูลีน - กล่าวอีกนัยหนึ่ง

ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().

เมื่อใช้เป็นค่าบูลีน นั่นเป็นเพราะมันไม่มีความชัดเจนเมื่อมันควรจะเป็นจริงหรือเท็จ ผู้ใช้บางคนอาจคิดว่าพวกเขาเป็นจริงหากพวกเขามีความยาวไม่เป็นศูนย์เช่นรายการ Python คนอื่นอาจต้องการให้มันเป็นจริงเฉพาะเมื่อองค์ประกอบทั้งหมดเป็นจริง คนอื่นอาจต้องการให้มันเป็นจริงถ้าองค์ประกอบใด ๆของมันเป็นจริง

เนื่องจากมีความคาดหวังที่ขัดแย้งกันมากนักออกแบบของ NumPy และ Pandas ปฏิเสธที่จะคาดเดาและยกระดับ ValueError แทน

แต่คุณจะต้องมีความชัดเจนโดยการเรียกempty(), all()หรือany()วิธีการในการระบุว่าพฤติกรรมที่คุณต้องการ

ในกรณีนี้ดูเหมือนว่าคุณไม่ต้องการการประเมินแบบบูลคุณต้องการองค์ประกอบที่ฉลาดและ นั่นคือสิ่งที่&ตัวดำเนินการไบนารีดำเนินการ:

(a['x']==1) & (a['y']==10)

ส่งกลับอาร์เรย์แบบบูล


โดยวิธีการที่เป็นบันทึก alexpmilวงเล็บที่มีผลบังคับใช้ตั้งแต่&มีสูงมีความสำคัญผู้ประกอบการ==กว่า โดยไม่ต้องวงเล็บที่a['x']==1 & a['y']==10จะได้รับการประเมินเป็นที่จะเปิดจะเทียบเท่ากับการเปรียบเทียบถูกล่ามโซ่a['x'] == (1 & a['y']) == 10 นั่นคือการแสดงออกของรูปแบบ(a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10) Series and Seriesการใช้งานandกับทั้งสองซีรี่ส์จะเรียกใช้เช่นเดียวกันValueErrorกับข้างบนอีกครั้ง นั่นเป็นเหตุผลว่าทำไมจึงจำเป็นต้องใส่วงเล็บ


3
อาร์เรย์ numpy มีคุณสมบัตินี้หากพวกเขามีความยาวหนึ่ง pandas เท่านั้น (ดื้อรั้น) ปฏิเสธที่จะคาดเดา: p
Andy Hayden

4
'&' ไม่ถือเส้นโค้งที่ไม่ชัดเจนเหมือนกับ 'และ' หรือไม่ ทำไมเมื่อถึง '&' ทันใดนั้นผู้ใช้ทุกคนก็เห็นด้วยว่าควรเป็นองค์ประกอบที่ชาญฉลาดในขณะที่เมื่อพวกเขาเห็น 'และ' ความคาดหวังของพวกเขาแตกต่างกันไป?
Indominus

16
@Indominus: ภาษางูหลามตัวเองต้องว่าการแสดงออกx and yเป็นต้นเหตุของการประเมินผลและbool(x) bool(y)Python ประเมินผลครั้งแรกxถ้าxเป็นเท็จค่าจะถูกส่งคืนมิฉะนั้นyจะถูกประเมินและส่งคืนค่าผลลัพธ์ ดังนั้นจึงx and yไม่สามารถใช้ไวยากรณ์สำหรับองค์ประกอบที่มีเหตุผลและเนื่องจากมีเพียงxหรือyสามารถส่งคืนได้ ในทางตรงกันข้ามx & yทริกเกอร์x.__and__(y)และ__and__วิธีการสามารถกำหนดให้คืนสิ่งที่เราชอบ
unutbu

2
สำคัญที่ควรทราบ: วงเล็บรอบ==ข้อที่มีผลบังคับใช้ a['x']==1 & a['y']==10ส่งคืนข้อผิดพลาดเดียวกับในคำถาม
Alex P. Miller

1
"|" มีไว้ทำอะไร?
Euler_Salter

62

TLDR; ผู้ประกอบการลอจิกในนุ่นมี&, |และ~และวงเล็บ(...)เป็นสิ่งสำคัญ!

and, orและnotดำเนินการทางตรรกะถูกออกแบบมาเพื่อทำงานร่วมกับสเกลา ดังนั้นนุ่นต้องทำอย่างใดอย่างหนึ่งให้ดีขึ้นและแทนที่โอเปอเรเตอร์บิตเตอร์ (องค์ประกอบที่ชาญฉลาด) ของการทำงานนี้

ดังนั้นต่อไปนี้ในหลาม ( exp1และexp2เป็นนิพจน์ที่ประเมินผลเป็นบูลีน) ...

exp1 and exp2              # Logical AND
exp1 or exp2               # Logical OR
not exp1                   # Logical NOT

... จะแปลเป็น ...

exp1 & exp2                # Element-wise logical AND
exp1 | exp2                # Element-wise logical OR
~exp1                      # Element-wise logical NOT

สำหรับแพนด้า

หากในกระบวนการของการดำเนินการทางตรรกะที่คุณได้รับValueErrorแล้วคุณจะต้องใช้วงเล็บสำหรับการจัดกลุ่ม:

(exp1) op (exp2)

ตัวอย่างเช่น,

(df['col1'] == x) & (df['col2'] == y) 

และอื่น ๆ


การจัดทำดัชนีบูลีน : การดำเนินการทั่วไปคือการคำนวณมาสก์บูลีนผ่านเงื่อนไขเชิงตรรกะเพื่อกรองข้อมูล Pandas จัดเตรียมโอเปอเรเตอร์สามรายการ :&สำหรับโลจิคัล AND และ,|ตรรกะ OR และโล~จิคัล NOT

พิจารณาการตั้งค่าต่อไปนี้:

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

ตรรกะและ

สำหรับตัวอย่างdfข้างต้นสมมติว่าคุณต้องการส่งคืนแถวทั้งหมดที่ A <5 และ B> 5 ​​ทำได้โดยการคำนวณมาสก์สำหรับแต่ละเงื่อนไขแยกจากกันและ ANDing พวกเขา

ล้น Bitwise &ผู้ประกอบการ
ก่อนที่จะดำเนินการต่อไปโปรดรับทราบข้อความที่ตัดตอนมานี้โดยเฉพาะเอกสารที่รัฐ

การดำเนินการทั่วไปอื่นคือการใช้เวกเตอร์บูลีนเพื่อกรองข้อมูล ผู้ประกอบการที่มี: |สำหรับor, &สำหรับand, และสำหรับ~ เหล่านี้จะต้องถูกจัดกลุ่มโดยใช้วงเล็บตั้งแต่เริ่มต้นโดยงูหลามจะประเมินการแสดงออกเช่นเป็นในขณะที่การสั่งซื้อการประเมินผลที่ต้องการคือnotdf.A > 2 & df.B < 3df.A > (2 & df.B) < 3(df.A > 2) & (df.B < 3)

ดังนั้นเมื่อคำนึงถึงเรื่องนี้แล้วองค์ประกอบฉลาดตรรกะและสามารถนำไปใช้กับตัวดำเนินการระดับบิต&:

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

และขั้นตอนการกรองที่ตามมาก็คือ

df[(df['A'] < 5) & (df['B'] > 5)]

   A  B  C
1  3  7  9
3  4  7  6

วงเล็บจะใช้ในการแทนที่เพื่อเริ่มต้นความสำคัญของผู้ประกอบการระดับบิตซึ่งมีความสำคัญสูงกว่าผู้ประกอบการที่มีเงื่อนไขและ< >ดูในส่วนของโอเปอเรเตอร์สำคัญใน python docs

หากคุณไม่ได้ใช้วงเล็บการแสดงออกจะถูกประเมินอย่างไม่ถูกต้อง ตัวอย่างเช่นหากคุณพยายามทำบางสิ่งเช่น

df['A'] < 5 & df['B'] > 5

มันแยกเป็น

df['A'] < (5 & df['B']) > 5

ซึ่งกลายเป็น

df['A'] < something_you_dont_want > 5

ซึ่งจะกลายเป็น (ดูเอกสารหลามในการเปรียบเทียบผู้ประกอบการที่ถูกล่ามโซ่ )

(df['A'] < something_you_dont_want) and (something_you_dont_want > 5)

ซึ่งกลายเป็น

# Both operands are Series...
something_else_you_dont_want1 and something_else_you_dont_want2

ซึ่งพ่น

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

ดังนั้นอย่าทำผิดพลาด! 1

การหลีกเลี่ยงวงเล็บการจัดกลุ่ม
การแก้ไขนั้นค่อนข้างง่าย ผู้ประกอบการส่วนใหญ่มีวิธีผูกพันที่สอดคล้องกันสำหรับ DataFrames หากมาสก์แต่ละตัวถูกสร้างขึ้นโดยใช้ฟังก์ชั่นแทนตัวดำเนินการตามเงื่อนไขคุณจะไม่ต้องจัดกลุ่มตามคำสั่งเพื่อระบุลำดับการประเมิน:

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

ดูส่วนที่เกี่ยวกับการเปรียบเทียบความยืดหยุ่น . เพื่อสรุปเรามี

╒════╤════════════╤════════════╕
     Operator    Function   
╞════╪════════════╪════════════╡
  0  >           gt         
├────┼────────────┼────────────┤
  1  >=          ge         
├────┼────────────┼────────────┤
  2  <           lt         
├────┼────────────┼────────────┤
  3  <=          le         
├────┼────────────┼────────────┤
  4  ==          eq         
├────┼────────────┼────────────┤
  5  !=          ne         
╘════╧════════════╧════════════╛

ตัวเลือกอื่นสำหรับการหลีกเลี่ยงวงเล็บคือการใช้DataFrame.query(หรือeval):

df.query('A < 5 and B > 5')

   A  B  C
1  3  7  9
3  4  7  6

ฉันได้อย่างกว้างขวางเอกสารqueryและevalในแบบไดนามิกการแสดงออกในการประเมินผลโดยใช้หมีแพนด้า pd.eval ()

operator.and_
ช่วยให้คุณสามารถดำเนินการนี้ในลักษณะการทำงาน เรียกภายในSeries.__and__ซึ่งสอดคล้องกับตัวดำเนินการระดับบิต

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

โดยปกติคุณจะไม่ต้องการสิ่งนี้ แต่มีประโยชน์ที่จะรู้

การสรุป: np.logical_and(และlogical_and.reduce)
อีกทางเลือกหนึ่งคือการใช้ 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เป็นufunc (ฟังก์ชั่นสากล)และ ufuncs ส่วนใหญ่มีreduceวิธีการ ซึ่งหมายความว่าเป็นการง่ายกว่าlogical_andหากคุณมีมาสก์หลายรายการให้กับและ ตัวอย่างเช่นการและมาสก์m1และm2และm3มี&คุณจะต้องทำ

m1 & m2 & m3

อย่างไรก็ตามตัวเลือกที่ง่ายกว่าคือ

np.logical_and.reduce([m1, m2, m3])

สิ่งนี้มีประสิทธิภาพเพราะช่วยให้คุณสามารถสร้างสิ่งเหล่านี้ได้ด้วยตรรกะที่ซับซ้อนมากขึ้น (ตัวอย่างเช่นการสร้างมาสก์แบบไดนามิกในรายการความเข้าใจและการเพิ่มพวกมันทั้งหมด):

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 - ฉันรู้ว่าฉันกำลังเล่นพิณในจุดนี้ แต่โปรดอดทนกับฉัน นี้เป็นอย่างมาก , มากผิดพลาดเริ่มต้นร่วมกันและจะต้องมีการอธิบายอย่างละเอียด


ตรรกะหรือ

สำหรับdfข้างต้นสมมติว่าคุณต้องการส่งคืนแถวทั้งหมดโดยที่ A == 3 หรือ B == 7

Bitwise มากเกินไป |

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

หากคุณยังไม่ได้โปรดอ่านส่วนในตรรกะและข้างต้นคำเตือนทั้งหมดใช้ที่นี่

หรือมิฉะนั้นการดำเนินการนี้สามารถระบุได้ด้วย

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__ใต้ฮูด

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
สำหรับสองเงื่อนไขให้ใช้logical_or:

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

สำหรับหน้ากากหลายอันให้ใช้logical_or.reduce:

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

ตรรกะไม่

รับหน้ากากเช่น

mask = pd.Series([True, True, False])

หากคุณต้องการสลับค่าบูลีนทุกค่า (เพื่อให้ได้ผลลัพธ์สุดท้าย[False, False, True]) คุณสามารถใช้วิธีการใดก็ได้ด้านล่าง

bitwise ~

~mask

0    False
1    False
2     True
dtype: bool

อีกครั้งนิพจน์ต้องถูกวงเล็บ

~(df['A'] == 3)

0     True
1    False
2    False
3     True
4     True
Name: A, dtype: bool

สิ่งนี้เป็นการโทรภายใน

mask.__invert__()

0    False
1    False
2     True
dtype: bool

แต่อย่าใช้โดยตรง

operator.inv
โทรภายใน__invert__ซีรี่ส์

operator.inv(mask)

0    False
1    False
2     True
dtype: bool

np.logical_not
นี่คือตัวแปรที่แตกต่าง

np.logical_not(mask)

0    False
1    False
2     True
dtype: bool

หมายเหตุnp.logical_andสามารถทดแทนnp.bitwise_and, logical_orมีbitwise_orและมีlogical_notinvert


@ cs95 ใน TLDR สำหรับบูลองค์ประกอบฉลาดหรือคุณสนับสนุนการใช้|ซึ่งเทียบเท่ากับการแทนnumpy.bitwise_or numpy.logical_orฉันขอถามทำไม ไม่ได้numpy.logical_orออกแบบมาสำหรับงานนี้โดยเฉพาะใช่ไหม ทำไมต้องเพิ่มภาระในการทำมันให้เหมาะสมสำหรับองค์ประกอบแต่ละคู่?
flow2k

@ flow2k คุณสามารถพูดข้อความที่เกี่ยวข้องได้ไหม? ฉันไม่พบสิ่งที่คุณอ้างถึง FWIW ฉันยืนยันว่า logical_ * เป็นฟังก์ชันการทำงานที่ถูกต้องของตัวดำเนินการ
cs95

@ cs95 ฉันหมายถึงบรรทัดแรกของคำตอบ: "TLDR; ตัวดำเนินการเชิงตรรกะใน Pandas คือ &, | และ ~"
flow2k

@ flow2k มันมีอยู่ในเอกสาร : "การดำเนินการทั่วไปอีกอย่างคือการใช้เวกเตอร์บูลีนเพื่อกรองข้อมูลตัวดำเนินการคือ: | สำหรับหรือ, & สำหรับและ, และ ~ สำหรับไม่ได้"
cs95

@ cs95 โอเคฉันเพิ่งอ่านส่วนนี้และมันใช้|สำหรับการดำเนินการบูลีนที่ชาญฉลาด แต่สำหรับฉันแล้วเอกสารนั้นเป็นมากกว่า "กวดวิชา" และในทางกลับกันฉันรู้สึกว่าการอ้างอิง API เหล่านี้อยู่ใกล้กับแหล่งที่มาของความจริง: numpy.bitwise_orและnumpy.logical_or - ดังนั้นฉันจึงพยายามเข้าใจว่าอะไรคือ อธิบายไว้ที่นี่
flow2k

4

ตัวดำเนินการเชิงตรรกะสำหรับการทำดัชนีบูลีนใน Pandas

มันเป็นสิ่งสำคัญที่จะรู้ว่าคุณไม่สามารถใช้ใด ๆ ของงูหลามดำเนินการทางตรรกะ ( and, orหรือnot) บนpandas.Seriesหรือpandas.DataFrames (ในทำนองเดียวกันคุณจะไม่สามารถใช้พวกเขาในnumpy.arrayS กับองค์ประกอบมากกว่าหนึ่ง) เหตุผลที่คุณไม่สามารถใช้สิ่งเหล่านี้ได้เพราะพวกเขาเรียกboolใช้ตัวถูกดำเนินการซึ่งส่งข้อยกเว้นโดยปริยายเนื่องจากโครงสร้างข้อมูลเหล่านี้ตัดสินใจว่าบูลีนของอาร์เรย์นั้นคลุมเครือ:

>>> import numpy as np
>>> import pandas as pd
>>> arr = np.array([1,2,3])
>>> s = pd.Series([1,2,3])
>>> df = pd.DataFrame([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> bool(df)
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

ฉันครอบคลุมสิ่งนี้มากขึ้นในคำตอบของฉันเกี่ยวกับ "ค่าความจริงของซีรี่ส์ไม่ชัดเจนใช้ a.empty, a.bool (), a.item (), a.any () หรือ a.all ()" Q + A

ฟังก์ชันตรรกะ NumPys

อย่างไรก็ตามNumPyให้องค์ประกอบที่ชาญฉลาดเทียบเท่าการดำเนินงานแก่ผู้ประกอบการเหล่านี้เป็นฟังก์ชั่นที่สามารถใช้บนnumpy.array, pandas.Series, pandas.DataFrameหรืออื่น ๆ (สอดคล้อง) ใด ๆnumpy.arrayประเภทรอง:

ดังนั้นหลักหนึ่งควรใช้ (สมมติdf1และdf2มีหมีแพนด้า DataFrames):

np.logical_and(df1, df2)
np.logical_or(df1, df2)
np.logical_not(df1)
np.logical_xor(df1, df2)

ฟังก์ชันระดับบิตและตัวดำเนินการระดับบิตสำหรับบูลีน

อย่างไรก็ตามในกรณีที่คุณมีบูลีน NumPy, pandas Series หรือ pandas DataFrames คุณสามารถใช้ฟังก์ชัน bitwise องค์ประกอบที่ชาญฉลาด (สำหรับ booleans พวกมัน - หรืออย่างน้อยก็ควรแยกไม่ออกจากฟังก์ชันตรรกะ):

  • bitwise และ: np.bitwise_andหรือตัว&ดำเนินการ
  • bitwise หรือ: np.bitwise_orหรือ| operator
  • bitwise not: np.invert(หรือนามแฝงnp.bitwise_not) หรือ~ผู้ประกอบการ
  • bitor xor: np.bitwise_xorหรือ^operator

โดยทั่วไปแล้วผู้ประกอบการจะใช้ อย่างไรก็ตามเมื่อรวมกับตัวดำเนินการเปรียบเทียบเราต้องจำไว้ว่าให้ปิดการเปรียบเทียบในวงเล็บเพราะตัวดำเนินการระดับบิตมีลำดับความสำคัญสูงกว่าตัวดำเนินการเปรียบเทียบ :

(df1 < 10) | (df2 > 10)  # instead of the wrong df1 < 10 | df2 > 10

สิ่งนี้อาจทำให้เกิดการระคายเคืองเนื่องจากตัวดำเนินการทางตรรกะของ Python มีความน่าเชื่อถือต่ำกว่าตัวดำเนินการเปรียบเทียบดังนั้นโดยปกติคุณจะเขียนa < 10 and b > 10(ที่ไหนaและbตัวอย่างเช่นจำนวนเต็มอย่างง่าย) และไม่จำเป็นต้องใช้วงเล็บ

ความแตกต่างระหว่างการดำเนินการทางตรรกะและระดับบิต

สิ่งสำคัญคือต้องเน้นว่าบิตและการดำเนินการแบบลอจิคัลนั้นเทียบเท่ากับอาร์เรย์บูลีน NumPy เท่านั้น (และบูลีนซีรี่ส์และ DataFrames) หากสิ่งเหล่านี้ไม่มีบูลีนการดำเนินการจะให้ผลลัพธ์ที่ต่างกัน ฉันจะรวมตัวอย่างโดยใช้อาร์เรย์ NumPy แต่ผลลัพธ์จะคล้ายกันกับโครงสร้างข้อมูลของแพนด้า:

>>> import numpy as np
>>> a1 = np.array([0, 0, 1, 1])
>>> a2 = np.array([0, 1, 0, 1])

>>> np.logical_and(a1, a2)
array([False, False, False,  True])
>>> np.bitwise_and(a1, a2)
array([0, 0, 0, 1], dtype=int32)

และเนื่องจาก NumPy (และแพนด้าในทำนองเดียวกัน) ทำสิ่งต่าง ๆ สำหรับบูลีน ( บูลีนหรือ "มาสก์" ดัชนีอาร์เรย์ ) และจำนวนเต็ม ( ดัชนีอาร์เรย์ ) ดัชนีผลของการจัดทำดัชนีจะแตกต่างกัน:

>>> a3 = np.array([1, 2, 3, 4])

>>> a3[np.logical_and(a1, a2)]
array([4])
>>> a3[np.bitwise_and(a1, a2)]
array([1, 1, 1, 2])

ตารางสรุป

Logical operator | NumPy logical function | NumPy bitwise function | Bitwise operator
-------------------------------------------------------------------------------------
       and       |  np.logical_and        | np.bitwise_and         |        &
-------------------------------------------------------------------------------------
       or        |  np.logical_or         | np.bitwise_or          |        |
-------------------------------------------------------------------------------------
                 |  np.logical_xor        | np.bitwise_xor         |        ^
-------------------------------------------------------------------------------------
       not       |  np.logical_not        | np.invert              |        ~

ที่ตัวดำเนินการโลจิคัลไม่ทำงานสำหรับอาร์เรย์ NumPy , pandas Series และ pandas DataFrames คนอื่น ๆ ทำงานกับโครงสร้างข้อมูลเหล่านี้ (และวัตถุ Python ธรรมดา) และองค์ประกอบการทำงานที่ชาญฉลาด อย่างไรก็ตามควรระวังด้วยการกลับด้านเล็กน้อยใน Python bools ธรรมดาเพราะบูลจะถูกตีความว่าเป็นจำนวนเต็มในบริบทนี้ (เช่น~Falseผลตอบแทน-1และ~Trueผลตอบแทน-2)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.