logical_or
Hàm của Numpy không cần nhiều hơn hai mảng để so sánh. Làm cách nào để tìm hợp nhất của nhiều hơn hai mảng? (Câu hỏi tương tự có thể được đặt ra liên quan đến Numpy's logical_and
và lấy giao điểm của nhiều hơn hai mảng.)
logical_or
Hàm của Numpy không cần nhiều hơn hai mảng để so sánh. Làm cách nào để tìm hợp nhất của nhiều hơn hai mảng? (Câu hỏi tương tự có thể được đặt ra liên quan đến Numpy's logical_and
và lấy giao điểm của nhiều hơn hai mảng.)
Câu trả lời:
Nếu bạn đang hỏi về numpy.logical_or
, thì không, như tài liệu nói rõ ràng, các tham số duy nhất là x1, x2
và tùy chọn out
:
numpy.
logical_or
(x1, x2[, out]
) =<ufunc 'logical_or'>
Tất nhiên, bạn có thể xâu chuỗi nhiều logical_or
cuộc gọi lại với nhau như thế này:
>>> 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)
Cách tổng quát hóa loại chuỗi này trong NumPy là với reduce
:
>>> np.logical_or.reduce((x, y, z))
array([ True, True, True, False], dtype=bool)
Và tất nhiên điều này cũng sẽ làm việc nếu bạn có một mảng đa chiều thay vì mảng trong thực tế riêng biệt, đó là cách nó có nghĩa là để được sử dụng:
>>> 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)
Nhưng một bộ ba mảng 1D có độ dài bằng nhau là một mảng_như theo thuật ngữ NumPy và có thể được sử dụng như một mảng 2D.
Ngoài NumPy, bạn cũng có thể sử dụng Python reduce
:
>>> functools.reduce(np.logical_or, (x, y, z))
array([ True, True, True, False], dtype=bool)
Tuy nhiên, không giống như NumPy's reduce
, Python không thường xuyên cần thiết. Đối với hầu hết các trường hợp, có một cách đơn giản hơn để thực hiện mọi việc — ví dụ: chuỗi nhiều or
toán tử Python lại với nhau , đừng reduce
kết thúc operator.or_
, chỉ cần sử dụng any
. Và khi có không phải là , nó thường dễ đọc hơn để sử dụng một vòng lặp rõ ràng.
Và trên thực tế, NumPy's any
cũng có thể được sử dụng cho trường hợp này, mặc dù nó không quá tầm thường; nếu bạn không cung cấp cho nó một trục rõ ràng, bạn sẽ kết thúc với một đại lượng vô hướng thay vì một mảng. Vì thế:
>>> np.any((x, y, z), axis=0)
array([ True, True, True, False], dtype=bool)
Như bạn có thể mong đợi, logical_and
cũng tương tự — bạn có thể xâu chuỗi nó, np.reduce
nó, functools.reduce
nó, hoặc thay thế all
bằng một cách rõ ràng axis
.
Điều gì về các hoạt động khác, như thế logical_xor
nào? Một lần nữa, cùng một thỏa thuận… ngoại trừ trường hợp này không có hàm all
/ any
-type nào được áp dụng. (Bạn sẽ gọi nó là gì odd
?)
np.logical_or.reduce((x, y, z))
chỉ là những gì tôi đang tìm kiếm!
reduce
không còn là một hàm nội bộ trong python 3. Thay vào đó, hãy sử dụng:functools.reduce()
Vì đại số boolean là cả giao hoán và kết hợp theo định nghĩa, các câu lệnh sau đây hoặc tương đương cho các giá trị boolean của a, b và c.
a or b or c
(a or b) or c
a or (b or c)
(b or a) or c
Vì vậy, nếu bạn có "logic_or" là dyadic và bạn cần chuyển cho nó ba đối số (a, b và c), bạn có thể gọi
logical_or(logical_or(a, b), c)
logical_or(a, logical_or(b, c))
logical_or(c, logical_or(b, a))
hoặc bất kỳ phép hoán vị nào bạn thích.
Quay lại python, nếu bạn muốn kiểm tra xem một điều kiện (được tạo ra bởi một hàm test
nhận testee và trả về giá trị boolean) có áp dụng cho a hoặc b hoặc c hoặc bất kỳ phần tử nào của danh sách L hay không, bạn thường sử dụng
any(test(x) for x in L)
or
không thực sự là boolean or
, cả vì nó hoạt động trên các giá trị khác với bool
s (trả về a
nếu a
là true, b
ngược lại) và vì nó ngắn mạch (nghĩa a or b
có thể là True, trong khi b or a
tạo ra một ngoại lệ).
Dựa trên câu trả lời của abarnert cho trường hợp n chiều:
TL; DR: np.logical_or.reduce(np.array(list))
Tôi sử dụng cách giải quyết này có thể được mở rộng cho n mảng:
>>> 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)
Tôi đã thử ba phương pháp khác nhau sau đây để lấy logical_and
danh sách l gồm k mảng có kích thước n :
numpy.logical_and
(xem bên dưới)numpy.logical_and.reduce(l)
numpy.vstack(l).all(axis=0)
Sau đó, tôi đã làm tương tự cho logical_or
chức năng. Đáng ngạc nhiên là phương pháp đệ quy là phương pháp nhanh nhất.
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
)
Dưới đây là các biểu diễn cho k = 4.
Và ở đây bên dưới biểu diễn cho k = 10.
Có vẻ như cũng có một khoảng thời gian không đổi gần như không đổi đối với n cao hơn.
any()
?