我有一個長度為“N”的布爾陣列的大樣本(M)。所以可能有 2^N 個唯一的布爾陣列。我想知道有多少陣列彼此重復并創建直方圖。
一種可能性是為每個唯一的陣列創建一個唯一的整數 (a[0] a[1]*2 a[3]*4 ... a[N]*2^(N-1)) 并且該整數的直方圖。
但這將是 O(M*N)。做這個的最好方式是什么?
uj5u.com熱心網友回復:
numpy.ravel_multi_index 能夠為您做到這一點:
arr = np.array([[True, True, True],
[True, False, True],
[True, False, True],
[False, False, False],
[True, False, True]], dtype=int)
nums = np.ravel_multi_index(arr.T, (2,) * arr.shape[1])
>>> nums
array([7, 5, 5, 0, 5], dtype=int64)
由于您需要直方圖,請使用
>>> np.histogram(nums, bins=np.arange(2**arr.shape[1] 1))
(array([1, 0, 0, 0, 0, 3, 0, 1], dtype=int64),
array([0, 1, 2, 3, 4, 5, 6, 7, 8]))
另一種選擇是使用np.unique:
>>> np.unique(arr, return_counts=True, axis=0)
(array([[0, 0, 0],
[1, 0, 1],
[1, 1, 1]]),
array([1, 3, 1], dtype=int64))
uj5u.com熱心網友回復:
使用矢量化操作,鍵的創建比 a[0] a[1]x2 a[3]x4 ... a[N]*2^(N-1) 快得多。我認為這不是更好的解決方案......在任何情況下,您幾乎都需要“讀取”每個值一次,這需要 MxN 步驟。
N = 3
M = 5
sample = [
np.array([True, True, True]),
np.array([True, False, True]),
np.array([True, False, True]),
np.array([False, False, False]),
np.array([True, False, True]),
]
multipliers = [2<<i for i in range(N-2, -1, -1)] [1]
buckets = {}
buck2vec = {}
for s in sample:
key = sum(s*multipliers)
if key not in buckets:
buckets[key] = 0
buck2vec[key] = s
buckets[key] =1
for key in buckets:
print(f"{buck2vec[key]} -> {buckets[key]} occurency")
結果:
[False False False] -> 1 occurency
[ True False True] -> 3 occurency
[ True True True] -> 1 occurency
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/368000.html
