[英]Frequency count per sub array or slice in a 3D NumPy array
我正在嘗試獲取 numpy 3d 陣列中每個子陣列的頻率計數(不含零)。 但是, scipy.stats.itemfreq 工具返回二維數組中的頻率計數。
我得到的是:
array_3d= array([[[1, 0, 0],
[1, 0, 0],
[0, 2, 0]],
[[0, 0, 0],
[0, 0, 3],
[3, 3, 3]],
[[0, 0, 4],
[0, 0, 4],
[0, 0, 4]]])
>>> itemfreq(array_3d)[1:,]
# outputs
array([ 1, 2],
[ 2, 1],
[ 3, 4],
[ 4, 3]], dtype=int64)
雖然我想要輸出:
array([[ 1, 2, 2, 1],
[ 3, 4],
[ 4, 3]], dtype=object)
這個想法是奇數總是唯一值,偶數總是頻率。
另一個輸出可能是:
array([ 1, 2, 0],
[ 2, 1, 0],
[ 3, 4, 1],
[ 4, 3, 2]], dtype=int64)
其中第三列表示 3d 數組中的子集數。
我也對其他輸出/解決方案持開放態度!
提前致謝!
方法#1
這是使用NumPy broadcasting
的矢量化方法 -
# Get unique non-zero elements
unq = np.unique(array_3d[array_3d!=0])
# Get matches mask corresponding to all array_3d elements against all unq elements
mask = array_3d == unq[:,None,None,None]
# Get the counts
sums = mask.sum(axis=(2,3)).T
# Indices of non-zero(valid) counts
Rvalid,Cvalid = np.where(sums!=0)
# Finally, pressent the output in the desired format
out = np.column_stack((unq[Cvalid],sums[sums!=0],Rvalid))
請注意,這將是一種資源匱乏的方法。
方法#2
這是另一種資源匱乏的方法,因此可能是首選 -
a2d = np.sort(array_3d.reshape(array_3d.shape[0],-1),axis=1)
start_mask = np.column_stack((a2d[:,0] !=0,np.diff(a2d,axis=1)>0))
unqID = a2d + ((np.arange(a2d.shape[0])*a2d.max())[:,None])
count = np.unique(unqID[a2d!=0],return_counts=True)[1]
out = np.column_stack((a2d[start_mask],count,np.where(start_mask)[0]))
請注意, count
也可以使用np.bincount
計算並且可能更快,就像這樣 -
C = np.bincount(unqID[a2d!=0])
count = C[C!=0]
numpy_indexed包(免責聲明:我是它的作者)可用於以優雅和矢量化的方式解決這個問題:
import numpy_indexed as npi
index = np.arange(array_3d.size) // array_3d[0].size
(value, index), count = npi.count((array_3d.flatten(), index))
這然后給出:
index = [0 0 0 1 1 2 2]
value = [0 1 2 0 3 0 4]
count = [6 2 1 5 4 6 3]
如果需要,可以通過索引值 > 0 對其進行后處理
Pandas 也為這個結果提供了直觀的方法:
df = pd.DataFrame(array_3d.reshape(3,9))
stats = df.apply(lambda x : unique(x,return_counts=True),axis=1)
result = stats.apply(lambda x : vstack(x)[:,1:].ravel())
為了
#stats
0 ([0, 1, 2], [6, 2, 1])
1 ([0, 3], [5, 4])
2 ([0, 4], [6, 3])
#result
0 [1, 2, 2, 1]
1 [3, 4]
2 [4, 3]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.