ブール値を含むnumpy配列がある場合、たとえば数学比較の出力など、その配列にTrue
sの連続したブロックが1つだけ含まれているかどうかを判断する最良の方法は何ですか?
array([False, False, False, True, True, True, False, False, False], dtype=bool)
つまり、シーケンス...,True, False, ..., True...
が発生しない場所は?
numpy
ネイティブなアプローチではありませんが、 を使用itertools.groupby
して連続値のブロックを 1 つの項目に減らし、 を使用して真の値のみが 1 回だけ表示されることを確認できますany
。は反復可能であるため、真の値が見つかるとすぐにgrouped
最初のany
戻り値が返されます。その後、反復可能の残りの部分のチェックを再開し、別の真の値がないことを確認します。True
from itertools import groupby
def has_single_true_block(sequence):
grouped = (k for k, g in groupby(sequence))
has_true = any(grouped)
has_another_true = any(grouped)
return has_true and not has_another_true
import numpy as np
def has_single_true_block(arr):
if not len(arr):
return False
blocks = len(np.array_split(arr, np.where(np.diff(arr) != 0)[0] + 1))
if blocks > 3:
return False
elif blocks == 3 and arr[0] and arr[-1]:
return False
elif blocks == 1 and not arr[0]: # 0 True blocks
return False
return True
# TESTS
a1 = np.array([False, False, True, True, True, False, False], dtype=bool)
has_single_true_block(a1) # => True
a2 = np.array([True, True, False, False], dtype=bool)
has_single_true_block(a2) # => True
a3 = np.array([False, False, True, True], dtype=bool)
has_single_true_block(a3) # => True
f1 = np.array([False, False, True, False, True, False, False], dtype=bool)
has_single_true_block(f1) # => False
f2 = np.array([True, True, False, False, True, True], dtype=bool)
has_single_true_block(f2) # => False
f3 = np.array([False, False, False], dtype=bool)
has_single_true_block(f3) # => False