Использование ИЛИ для уменьшения 3D-логического массива до 2D - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть логический массив 3D (5830L, 6447L, 4L), который я хочу уменьшить до (5830L, 6447L), используя логический оператор OR для 3-го измерения (4L). Поэтому я буду делать поэлементное сравнение 4L 2D массивов. Простой одномерный пример будет выглядеть примерно так:

a = [True, False, True]
b = [False, False, True]
c = [True, False, True]
mask = [any(tup) for tup in zip(a, b, c)]
print mask
'True, False, True'

Размер 3-го измерения может варьироваться, поэтому мне нужно запустить его в цикле for или запустить его таким образом, чтобы размер 3-го измерения не был жестко запрограммирован, как указано выше. numpy.logical_or(a, b) работает хорошо, но только для 2 элементов массива (2L).

Любой идеал, как это сделать, когда его 3 или более элементов; то есть третье измерение> 2L?

1 Ответ

0 голосов
/ 10 сентября 2018

Два варианта: используйте .reduce метод ufunc или используйте any (что совпадает с повторением ИЛИ для логических значений):

In [195]: x = np.random.choice([False, True], (5830, 6447, 4))

In [196]: via_reduce = np.logical_or.reduce(x, axis=2)

In [197]: via_any = x.any(axis=2)

In [198]: via_manual = np.logical_or(np.logical_or(np.logical_or(x[..., 0], x[..., 1]), x[..., 2]), x[...,3])

In [199]: np.allclose(via_reduce, via_any)
Out[199]: True

In [200]: np.allclose(via_reduce, via_manual)
Out[200]: True

Если честно, я ожидал, что .any будет значительно быстрее, но здесь нет большой разницы:

In [201]: %timeit via_reduce = np.logical_or.reduce(x, axis=2)
883 ms ± 2.99 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [202]: %timeit via_any = x.any(axis=2)
895 ms ± 7.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
...