классифицировать np.arrays как дубликаты - PullRequest
2 голосов
/ 11 июля 2019

Моя цель - взять список из np.array s и создать связанный список или массив, который классифицирует каждый из них как дубликат или нет. Вот то, что я думал, будет работать:

www = [np.array([1, 1, 1]), np.array([1, 1, 1]), np.array([2, 1, 1])]
uniques, counts = np.unique(www, axis = 0, return_counts = True)
counts = [1 if x > 1 else 0 for x in counts]
count_dict = dict(zip(uniques, counts))
[count_dict[i] for i in www]

Желаемый результат для этого случая будет:

[1, 1, 0]

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

Предложения

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

Сначала преобразуйте www в двумерный массив Numpy, затем выполните следующее:

In [18]: (counts[np.where((www[:,None] == uniques).all(2))[1]] > 1).astype(int)
Out[18]: array([1, 1, 0])

здесь мы используем трансляцию для проверки равенства всех www строк с массивом uniques, а затем с помощью all() на последней оси, чтобы выяснить, какие из ее строк полностью равны uniques строкам.

Вот подробные результаты:

In [20]: (www[:,None] == uniques).all(2)
Out[20]: 
array([[ True, False],
       [ True, False],
       [False,  True]])

# Respective indices in `counts` array
In [21]: np.where((www[:,None] == uniques).all(2))[1]
Out[21]: array([0, 0, 1])

In [22]: counts[np.where((www[:,None] == uniques).all(2))[1]] > 1
Out[22]: array([ True,  True, False])

In [23]: (counts[np.where((www[:,None] == uniques).all(2))[1]] > 1).astype(int)
Out[23]: array([1, 1, 0])
1 голос
/ 11 июля 2019

В Python списки (и числовые массивы) не могут быть хэшированы, поэтому они не могут использоваться в качестве ключей словаря. Но кортежи могут! Поэтому одним из вариантов будет преобразование исходного списка в кортеж и преобразование uniques в кортеж. У меня работает следующее:

www = [np.array([1, 1, 1]), np.array([1, 1, 1]), np.array([2, 1, 1])]
www_tuples = [tuple(l) for l in www]  # list of tuples
uniques, counts = np.unique(www, axis = 0, return_counts = True)
counts = [1 if x > 1 else 0 for x in counts]
# convert uniques to tuples
uniques_tuples = [tuple(l) for l in uniques]
count_dict = dict(zip(uniques_tuples, counts))
[count_dict[i] for i in www_tuples]

Просто наперед: это удвоит ваше потребление памяти, поэтому, возможно, оно не будет лучшим решением, если www велико. Вы можете уменьшить дополнительное потребление памяти, по мере возможности загружая данные в виде кортежей, а не в виде пустых массивов.

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