Определите все уникальные комбинации по третьему измерению массивов 2D numpy в стеке - PullRequest
1 голос
/ 27 января 2020

Для 2 или более двумерных целых numpy массивов, расположенных вдоль axis=0, меня интересует:

  1. , идентифицирующая все уникальные числовые комбинации в третьем измерении.
  2. помечает каждую комбинацию новым числовым значением («метки»)
  3. создает новый 2D-массив, где значения массива представляют собой метки, обозначающие комбинацию числовых значений исходных массивов.

Пример данных:

import numpy as np
arr1 = np.array(np.random.randint(low=0, high=4, size=25)).reshape(5,5)
arr2 = np.array(np.random.randint(low=0, high=4, size=25)).reshape(5,5)

Можно получить список кортежей интересующих комбинаций:

xx, yy = np.meshgrid(arr1, arr2, sparse=True)
combis = np.stack([xx.reshape(arr1.size), yy.reshape(arr2.size)])
u_combis = np.unique(combis, axis=1)
u_combis_lst = list(map(tuple, u_combis.T))

Создать словарь для сопоставления каждой комбинации с меткой:

labels = [x for x in range(0, len(u_combis_lst))]
label_dict = dict(zip(u_combis_lst, labels))

Теперь пункты 1 и 2, кажется, достигнуты. Мои вопросы:

  1. Как я могу применить label_dict к arr1 и arr2 в сочетании?
  2. Как улучшить мои предложения по коду?
  3. Как код может работать с> 2 массивами?

Чтобы завершить, я хочу воссоздать функциональность 'Объединить' в Arcgis Pro .

Ответы [ 2 ]

2 голосов
/ 29 января 2020

Другим подходом может быть создание таблицы поиска по словарю на основе уникальных комбинаций кортежей значений массива.

# start with flattened arrays
arr1 = np.random.randint(low=0, high=4, size=25)
arr2 = np.random.randint(low=0, high=4, size=25)

# create tuples and store the unique tuples
combis = list(zip(arr1, arr2)) 

u_combis = set(combis) # get unique combinations

# create a dictionary of the unique tuples with the unique values
u_combi_dict = {combi:n for n, combi in enumerate(u_combis)}

# use the unique dictionary combinations to match the tuples
combi_arr = np.array([u_combi_dict[combi] for combi in combis])

# if needed, reshape back to original extent for spatial analysis
combi_arr_grid = combi_arr.reshape(5, 5)

Функция generi c, которая может использовать произвольное количество входных массивов, может работать следующим образом:

def combine(input_arrays):

    combis = list(zip(*input_arrays))
    u_combis = set(combis)

    u_combi_dict = {combi: n for n, combi in enumerate(u_combis)}
    combi_arr = np.array([u_combi_dict[combi] for combi in combis])

    return combi_arr
1 голос
/ 28 января 2020

Если ваши числа маленькие sh числа, например np.uint8 (например, метки в неконтролируемой классификации), вы можете сдвинуть и ИЛИ слои вместе в толстое 64-битное целое и объединить их с этим - что позволит вам объединить до 8 np.uint8 слоев или 4 np.int16 слоев, например.

#!/usr/bin/env python3

import numpy as np

# Ensure repeatable, deterministic randomness!
np.random.seed(42)

# Generate test arrays
arr2 = np.array(np.random.randint(low=0, high=4, size=25)).reshape(5,5)
arr1 = np.array(np.random.randint(low=0, high=4, size=25)).reshape(5,5)

# Build a FatThing by shifting and ORing arrays together, do 3 arrays with FatThing = arr1 | (arr2<<8) | (arr3(<<16)
FatThing = arr1 | (arr2<<8)

# Find unique values in FatThing
uniques = np.unique(FatThing)

# Make lookup table of labels corresponding to each fat value
FatThing2label = {uniques[i]:i for i in range(len(uniques))}

# Lookup label of each fat value
result = [FatThing2label[int(x)] for x in np.nditer(FatThing)]
result = np.array(result).reshape(arr1.shape)

, который генерирует arr1 как:

array([[1, 1, 1, 3, 3],
       [0, 0, 3, 1, 1],
       [0, 3, 0, 0, 2],
       [2, 2, 1, 3, 3],
       [3, 3, 2, 1, 1]])

И arr2 as:

array([[2, 3, 0, 2, 2],
       [3, 0, 0, 2, 1],
       [2, 2, 2, 2, 3],
       [0, 3, 3, 3, 2],
       [1, 0, 1, 3, 3]])

Что делает FatThing похожим на это:

array([[513, 769,   1, 515, 515],
       [768,   0,   3, 513, 257],
       [512, 515, 512, 512, 770],
       [  2, 770, 769, 771, 515],
       [259,   3, 258, 769, 769]])

И result это:

array([[ 8, 11,  1,  9,  9],
       [10,  0,  3,  8,  4],
       [ 7,  9,  7,  7, 12],
       [ 2, 12, 11, 13,  9],
       [ 6,  3,  5, 11, 11]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...