私は次の問題を解決しようとしています。1からnまでの領域にラベル付けされたnumpy配列があります。これが配列だとしましょう:
x = np.array([[1, 1, 1, 4], [1, 1, 2, 4], [1, 2, 2, 4], [5, 5, 3, 4]], np.int32)
array([[1, 1, 1, 4],
[1, 1, 2, 4],
[1, 2, 2, 4],
[5, 5, 3, 4]])
領域は、一意の値を持つnumpy配列内の結合されたセルです。したがって、この例では、xには5つの領域があります。5つのセルで構成される領域1、3つのセルで構成される領域2など。ここで、次のコード行を使用して、各領域の隣接する領域を決定します。
n = x.max()
tmp = np.zeros((n+1, n+1), bool)
# check the vertical adjacency
a, b = x[:-1, :], x[1:, :]
tmp[a[a!=b], b[a!=b]] = True
# check the horizontal adjacency
a, b = x[:, :-1], x[:, 1:]
tmp[a[a!=b], b[a!=b]] = True
# register adjacency in both directions (up, down) and (left,right)
result = (tmp | tmp.T)
result = result.astype(int)
np.column_stack(np.nonzero(result))
resultlist = [np.flatnonzero(row) for row in result[1:]]
これにより、各リージョンとその隣接リージョンのリストが表示されます。
[array([2, 4, 5], dtype=int64),
array([1, 3, 4, 5], dtype=int64),
array([2, 4, 5], dtype=int64),
array([1, 2, 3], dtype=int64),
array([1, 2, 3], dtype=int64)]
これは本当にうまくいきます。ただし、隣接する各領域のセル数をカウントして、この出力を返したいと思います。したがって、リージョン2の場合、この例では、合計7つの隣接するリージョン(3つの1、2つの4、1つの3、および1つの5)を意味します。したがって:
上記のコードを調整して、隣接する各領域のセルの量を含めるにはどうすればよいですか?みんなありがとう!
これは、numpy_indexedパッケージを使用したベクトル化されたソリューションです(注;領域ではベクトル化されていませんが、ピクセルではベクトル化されています。これは、n_pixels >> n_regionsと仮定して行うと便利です):
neighbors = np.concatenate([x[:, :-1].flatten(), x[:, +1:].flatten(), x[+1:, :].flatten(), x[:-1, :].flatten()])
centers = np.concatenate([x[:, +1:].flatten(), x[:, :-1].flatten(), x[:-1, :].flatten(), x[+1:, :].flatten()])
valid = neighbors != centers
import numpy_indexed as npi
regions, neighbors_per_regions = npi.group_by(centers[valid], neighbors[valid])
for region, neighbors_per_region in zip(regions, neighbors_per_regions):
print(region)
unique_neighbors, neighbor_counts = npi.count(neighbors_per_region)
print(unique_neighbors, neighbor_counts / neighbor_counts.sum() * 100)
または、ピクセルと領域の両方で完全にベクトル化されたソリューションの場合:
(neighbors, centers), counts = npi.count((neighbors[valid], centers[valid]))
region_group = group_by(centers)
regions, neighbors_per_region = region_group.sum(counts)
fractions = counts / neighbors_per_region[region_group.inverse]
for q in zip(centers, neighbors, fractions): print(q)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加