logical_or
ฟังก์ชันของ Numpy ใช้อาร์เรย์ไม่เกินสองอาร์เรย์ในการเปรียบเทียบ ฉันจะหาการรวมกันของอาร์เรย์มากกว่าสองอาร์เรย์ได้อย่างไร (คำถามเดียวกันนี้สามารถถามได้เกี่ยวกับ Numpy logical_and
และการได้รับจุดตัดของอาร์เรย์มากกว่าสองอาร์เรย์)
logical_or
ฟังก์ชันของ Numpy ใช้อาร์เรย์ไม่เกินสองอาร์เรย์ในการเปรียบเทียบ ฉันจะหาการรวมกันของอาร์เรย์มากกว่าสองอาร์เรย์ได้อย่างไร (คำถามเดียวกันนี้สามารถถามได้เกี่ยวกับ Numpy logical_and
และการได้รับจุดตัดของอาร์เรย์มากกว่าสองอาร์เรย์)
คำตอบ:
หากคุณกำลังถามเกี่ยวกับnumpy.logical_or
ไม่อย่างที่เอกสารกล่าวอย่างชัดเจนพารามิเตอร์เดียวคือx1, x2
และเป็นทางเลือกout
:
numpy.
logical_or
(x1, x2[, out]
) =<ufunc 'logical_or'>
แน่นอนคุณสามารถเชื่อมโยงการlogical_or
โทรหลายสายเข้าด้วยกันเช่นนี้:
>>> x = np.array([True, True, False, False])
>>> y = np.array([True, False, True, False])
>>> z = np.array([False, False, False, False])
>>> np.logical_or(np.logical_or(x, y), z)
array([ True, True, True, False], dtype=bool)
วิธีสรุปการผูกมัดประเภทนี้ใน NumPy คือreduce
:
>>> np.logical_or.reduce((x, y, z))
array([ True, True, True, False], dtype=bool)
และแน่นอนนี้จะทำงานถ้าคุณมีอาร์เรย์หนึ่งหลายมิติแทนการแยกต่างหากอาร์เรย์ในความเป็นจริงที่ว่ามันหมายถึงการที่จะใช้:
>>> xyz = np.array((x, y, z))
>>> xyz
array([[ True, True, False, False],
[ True, False, True, False],
[False, False, False, False]], dtype=bool)
>>> np.logical_or.reduce(xyz)
array([ True, True, True, False], dtype=bool)
แต่ทูเพิลของอาร์เรย์ 1D ที่มีความยาวเท่ากันสามอาร์เรย์นั้นเป็นarray_likeในแง่ NumPy และสามารถใช้เป็นอาร์เรย์ 2D ได้
นอกจาก NumPy คุณยังสามารถใช้ Python's reduce
:
>>> functools.reduce(np.logical_or, (x, y, z))
array([ True, True, True, False], dtype=bool)
อย่างไรก็ตามไม่เหมือนกับ NumPy ของreduce
Python มักไม่จำเป็น สำหรับกรณีส่วนใหญ่มีวิธีที่ง่ายที่จะทำสิ่ง-เช่นโซ่กันหลามหลายor
ผู้ประกอบการไม่ได้reduce
มากกว่าการใช้เพียงoperator.or_
any
และเมื่อไม่มีก็มักจะอ่านได้ง่ายกว่าที่จะใช้การวนซ้ำอย่างชัดเจน
และในความเป็นจริง NumPy any
สามารถใช้กับกรณีนี้ได้เช่นกันแม้ว่าจะไม่เป็นเรื่องเล็กน้อย ถ้าคุณไม่ระบุแกนอย่างชัดเจนคุณจะจบลงด้วยสเกลาร์แทนอาร์เรย์ ดังนั้น:
>>> np.any((x, y, z), axis=0)
array([ True, True, True, False], dtype=bool)
ในขณะที่คุณอาจคาดหวังlogical_and
จะคล้ายคุณสามารถโซ่มันnp.reduce
มันfunctools.reduce
มันหรือทดแทนที่มีอย่างชัดเจนall
axis
สิ่งที่เกี่ยวกับการดำเนินการอื่น ๆ เช่นlogical_xor
? อีกครั้งข้อตกลงเดียวกัน ... ยกเว้นว่าในกรณีนี้จะไม่มีฟังก์ชันall
/ any
-type ที่ใช้ (คุณจะเรียกมันว่าอะไรodd
?)
np.logical_or.reduce((x, y, z))
เป็นเพียงสิ่งที่ฉันกำลังมองหา!
reduce
ไม่ใช่ฟังก์ชันภายในใน python 3 อีกต่อไปให้ใช้:functools.reduce()
ในกรณีที่มีคนยังคงต้องนี้ - พูดคุณมีสามอาร์เรย์แบบบูลa
, b
, c
ที่มีรูปร่างเหมือนกันนี้จะช่วยให้and
องค์ประกอบที่ชาญฉลาด:
a * b * c
สิ่งนี้ให้or
:
a + b + c
นี่คือสิ่งที่คุณต้องการหรือไม่? ซ้อนกันมากlogical_and
หรือlogical_or
ไม่สามารถใช้งานได้จริง
เนื่องจากอัลเจอร์บราแบบบูลีนมีทั้งแบบสับเปลี่ยนและเชื่อมโยงตามคำจำกัดความข้อความต่อไปนี้หรือเทียบเท่าสำหรับค่าบูลีนของ a, b และ c
a or b or c
(a or b) or c
a or (b or c)
(b or a) or c
ดังนั้นหากคุณมี "logical_or" ซึ่งเป็น dyadic และคุณต้องส่งผ่านอาร์กิวเมนต์สามตัว (a, b และ c) คุณสามารถเรียก
logical_or(logical_or(a, b), c)
logical_or(a, logical_or(b, c))
logical_or(c, logical_or(b, a))
หรือการเปลี่ยนแปลงใด ๆ ที่คุณต้องการ
กลับไปที่ python หากคุณต้องการทดสอบว่าเงื่อนไข (ที่ให้ผลโดยฟังก์ชันtest
ที่รับ testee และส่งกลับค่าบูลีน) ใช้กับ a หรือ b หรือ c หรือองค์ประกอบใด ๆ ของรายการ L คุณจะใช้ตามปกติ
any(test(x) for x in L)
or
ไม่ได้เป็นบูลีนจริงๆor
ทั้งคู่เพราะมันทำงานกับค่าอื่นที่ไม่ใช่bool
s (ส่งคืนa
ถ้าa
เป็นจริงไม่b
เช่นนั้น) และเนื่องจากมันลัดวงจร (ความหมายa or b
อาจเป็นจริงในขณะที่b or a
มีข้อยกเว้น)
จากคำตอบของ abarnert สำหรับกรณี n มิติ:
TL; DR: np.logical_or.reduce(np.array(list))
โดยใช้ฟังก์ชัน sum:
a = np.array([True, False, True])
b = array([ False, False, True])
c = np.vstack([a,b,b])
Out[172]:
array([[ True, False, True],
[False, False, True],
[False, False, True]], dtype=bool)
np.sum(c,axis=0)>0
Out[173]: array([ True, False, True], dtype=bool)
ฉันใช้วิธีแก้ปัญหานี้ซึ่งสามารถขยายไปยัง n อาร์เรย์:
>>> a = np.array([False, True, False, False])
>>> b = np.array([True, False, False, False])
>>> c = np.array([False, False, False, True])
>>> d = (a + b + c > 0) # That's an "or" between multiple arrays
>>> d
array([ True, True, False, True], dtype=bool)
ฉันได้ลองสามวิธีต่อไปนี้เพื่อรับlogical_and
รายการlของkอาร์เรย์ขนาดn :
numpy.logical_and
(ดูด้านล่าง)numpy.logical_and.reduce(l)
numpy.vstack(l).all(axis=0)
จากนั้นฉันก็ทำเช่นเดียวกันสำหรับlogical_or
ฟังก์ชัน น่าแปลกที่วิธีการเรียกซ้ำเป็นวิธีที่เร็วที่สุด
import numpy
import perfplot
def and_recursive(*l):
if len(l) == 1:
return l[0].astype(bool)
elif len(l) == 2:
return numpy.logical_and(l[0],l[1])
elif len(l) > 2:
return and_recursive(and_recursive(*l[:2]),and_recursive(*l[2:]))
def or_recursive(*l):
if len(l) == 1:
return l[0].astype(bool)
elif len(l) == 2:
return numpy.logical_or(l[0],l[1])
elif len(l) > 2:
return or_recursive(or_recursive(*l[:2]),or_recursive(*l[2:]))
def and_reduce(*l):
return numpy.logical_and.reduce(l)
def or_reduce(*l):
return numpy.logical_or.reduce(l)
def and_stack(*l):
return numpy.vstack(l).all(axis=0)
def or_stack(*l):
return numpy.vstack(l).any(axis=0)
k = 10 # number of arrays to be combined
perfplot.plot(
setup=lambda n: [numpy.random.choice(a=[False, True], size=n) for j in range(k)],
kernels=[
lambda l: and_recursive(*l),
lambda l: and_reduce(*l),
lambda l: and_stack(*l),
lambda l: or_recursive(*l),
lambda l: or_reduce(*l),
lambda l: or_stack(*l),
],
labels = ['and_recursive', 'and_reduce', 'and_stack', 'or_recursive', 'or_reduce', 'or_stack'],
n_range=[2 ** j for j in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
equality_check=None
)
ด้านล่างการแสดงสำหรับ k = 4
และด้านล่างการแสดงสำหรับ k = 10
ดูเหมือนว่าจะมีค่าใช้จ่ายเวลาคงที่โดยประมาณสำหรับ n ที่สูงขึ้น
any()
เหรอ?