Numpy уникальная функция - PullRequest
       0

Numpy уникальная функция

0 голосов
/ 22 февраля 2020

У меня быстрый вопрос о функции numpy unique. Я хочу вернуть уникальные значения столбцов для каждой строки

import numpy as np

a = np.array([[3, 2, 3, 2, 1, 3, 1, 2, 1, 3, 1, 2, 2, 2, 3, 3],
              [3, 2, 3, 2, 3, 3, 3, 3, 2, 2, 3, 1, 2, 1, 2, 1],
              [3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 3, 2, 2, 3, 1, 1]]) # a.shape is (3,16)



np.unique(a)
array([1, 2, 3]) # not what I want

np.unique(a,axis=1)
array([[1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3],
       [2, 3, 1, 1, 2, 2, 3, 1, 2, 2, 3],
       [2, 3, 2, 3, 2, 3, 2, 1, 1, 2, 3]]) # also not what I want, and I'm not even sure what its doing

np.apply_along_axis(np.unique,1,a)
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]]) # this is what I want

Проблема заключается в том, что я также хочу использовать другие функции np.unqiue, такие как возвращение значений индекса. Может ли кто-нибудь помочь мне заставить np.unique работать самостоятельно?

Ответы [ 2 ]

0 голосов
/ 22 февраля 2020

numpy не сможет вернуть матрицу со строками разных размеров. в вашем примере ровно 3 различных значения в строке, что делает np.apply_along_axis работоспособным, но если бы у вас было значение 4 в одной из строк или только 1 и 2 в строке, это не получилось бы.

Чтобы получить то, что вы ищите, вам нужно будет использовать обычный список Python в качестве результата. Вы можете построить его, используя понимание списка:

import numpy as np

a = np.array([[1, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1, 1],
              [3, 2, 3, 2, 3, 3, 3, 3, 2, 2, 3, 1, 2, 1, 2, 1],
              [3, 3, 3, 2, 3, 3, 4, 2, 2, 2, 3, 2, 2, 3, 1, 1]]) 

r = [ np.unique(row) for row in a ]
print(r)
# [array([1, 2]), array([1, 2, 3]), array([1, 2, 3, 4])]

r = [ np.unique(row,return_index=True)for row in a ]
print(r)
# [(array([1, 2]), array([0, 1])), 
#  (array([1, 2, 3]), array([11,  1,  0])), 
#  (array([1, 2, 3, 4]), array([14,  3,  0,  6]))]

Одна вещь, которую вы можете сделать, это создать маску значений, которые являются первыми в своем роде в каждой строке. Это можно сделать, используя numpy.

Вот один из способов сделать это (надеюсь, эксперты numpy могли бы предложить что-то менее запутанное):

np.sum(np.cumsum(np.cumsum(a==np.unique(a)[:,None,None],axis=2),axis=2)==1,axis=0)

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

Такая маска предлагает много обработки такие параметры, как поиск индексов первого вхождения в каждой строке (используя np.argwhere), удаление / назначение первого или последующих вхождений и т. д.

0 голосов
/ 22 февраля 2020

Вы можете l oop над строками и собирать уникальные значения:

import numpy as np

a = np.array([[3, 2, 3, 2, 1, 3, 1, 2, 1, 3, 1, 2, 2, 2, 3, 3],
              [3, 2, 3, 2, 3, 3, 3, 3, 2, 2, 3, 1, 2, 1, 2, 1],
              [3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 3, 2, 2, 3, 1, 1]])

arr = np.empty((0,3), int)
for row in a:
    arr = np.append(arr, np.array([np.unique(a)]), axis=0)

Выход:

[[1 2 3]
 [1 2 3]
 [1 2 3]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...