Преобразование 2d-массива в 2d-массив уникальных значений в строке - PullRequest
0 голосов
/ 09 мая 2020

У меня есть 2d-массив формы 5x4 вроде этого:

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

И я хотел бы получить еще один массив, содержащий массивы уникальных значений, примерно так:

array([array([3]), array([3]), array([2, 3]), array([2]), array([2])],
      dtype=object)

Я получил это с помощью следующего кода:

np.array([np.unique(row) for row in matrix])

Однако это не векторизовано. Как я мог добиться того же в векторизованной операции numpy?

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Вот один из способов минимизировать вычислительные ресурсы при итерации, который должен помочь повысить производительность -

b = np.sort(a,axis=1)
o = np.ones((len(a),1), dtype=bool)
mask = np.c_[o,b[:,:-1] != b[:,1:]]
c = b[mask]
out = np.split(c, mask.sum(1).cumsum())[:-1]

l oop для использования slicing может быть лучше, чем np.split. Итак, с каждой итерацией все, что мы делаем, будет нарезать. Следовательно, последний шаг можно было бы заменить на что-то вроде этого -

idx = np.r_[0,mask.sum(1).cumsum()]
out = []
for (i,j) in zip(idx[:-1],idx[1:]):
    out.append(c[i:j])
1 голос
/ 09 мая 2020

numpy массивы должны иметь определенную форму, поэтому, если ваши данные имеют только 1 значение для некоторых строк и 2 или более для других, то этого не будет. Обходной путь - заполнить массив известным значением, например. np.nan.

В этом случае np.unique рассортирует все за вас. Если вы используете его аргумент axis. В этом случае вам нужны уникальные значения для каждой строки, поэтому мы используем axis=1:

arr = np.array([[3, 3, 3, 3],
                [3, 3, 3, 3],
                [3, 3, 2, 2],
                [2, 2, 2, 2],
                [2, 2, 2, 2]])

np.unique(arr, axis=1)
>>> array([[3, 3],
           [3, 3],
           [2, 3],
           [2, 2],
           [2, 2]])

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

...