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
, และสำหรับ~
เหล่านี้จะต้องถูกจัดกลุ่มโดยใช้วงเล็บตั้งแต่เริ่มต้นโดยงูหลามจะประเมินการแสดงออกเช่นเป็นในขณะที่การสั่งซื้อการประเมินผลที่ต้องการคือnot
df.A > 2 & df.B < 3
df.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_not
invert