2016-12-10 3 views
0

У меня есть большой список, который выглядит примерно так (но способ больше)Сравнение элементов списка массивов

lista = [(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 1.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.]))] 

Вы не можете увидеть его в маленьком экстракте я поставил, но есть некоторые элементы, которые повторение. Мне нужно, чтобы дубликаты исчезли.

Я попытался сделать

newlist = [] 
for a in lista: 
    if np.all(a not in newlist): 
     newlist.append(a) 

Но он не работает, и он возвращает

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

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

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

(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])) 
+0

ли дублирующие элементы массивов сами по себе, или элементы внутри основного списка? – TheNavigat

+0

, это будет, например, '(array ([0., 0., 0.]), array ([0., 0., 0.]), array ([0., 0., 0.])) ' –

+0

Пока неясно, что вы определяете как« дубликаты ». Вы хотите удалить дубликаты массивов для каждого кортежа внутри вашего списка? или удалить дублированные массивы по всем кортежам в вашем списке? – sirfz

ответ

1

Ваше определение дубликата: кортеж с точно такими же массивами, которые повторяются в списке.

import numpy as np 

# list with the 5th tuple being a duplicate of the 1st 
lista = [(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
     (array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.])), 
     (array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 0.])), 
     (array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 1.])), 
     (array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
     (array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
     (array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.]))] 

clean_list = [] 

for t in lista: 
    for ut in clean_list: 
     if all(np.all(t[i] == ut[i]) for i in range(len(t)))): 
      # duplicate, discard it 
      break 
    else: 
     # does not exist, keep it 
     clean_list.append(t) 

Результат clean_list будет содержать все кортежи, за исключением 5-го кортежа, который является копией 1-го.

Обратите внимание, что в этом примере используется функция Python, встроенная функция all, для проверки правды всех переданных ей условий и numpy.all для проверки равенства всех элементов в сравниваемых массивах.

+0

Я не понимаю, что он делает, но он работает на полпути. он удаляет больше элементов, чем нужно. Как и элемент, который существует, это '([0., 0., 0.], [0., 0., 0.], [0., 0., 1.])' But '([0., 0 ., 0.], [0., 0., 0.], [0., 0., 2.]) 'Также существует, и он сохраняет только тот, который имеет наибольшее число (он должен содержать оба). –

+0

Он удаляет только кортежи, которые содержат ровно равные массивы. Обновите свой вопрос примерами текущего вывода и фактическим выводом. – sirfz

+0

Хорошо, конечно, пришлось настраивать цикл, который существовал для его работы (цикл создал 'lista', поэтому его нужно было изменить). Это работает, проблема в том, что он удаляет кортеж, содержащий все массивы нулей. –

0

Я не совсем уверен, что вы используете метод «все» правильно, хотя я не знаком с ним. Вот ссылка: https://docs.scipy.org/doc/numpy/reference/generated/numpy.all.html

не могли бы вы сделать ?:

newlist = [] 
for a in lista: 
    if a not in newlist: 
     newlist.append(a) 
+0

Я получаю ту же ошибку, если я поставлю этот код. Поскольку ошибка говорит о том, что она связана с '.all()' или '.any()', подумал, что добавив ее таким образом, она исправит ее, но это не так. –

+0

Просто обновил мой пост, вам нужно хранить массивы? – Ben

+0

Да, мне нужно сохранить все элементы, как они есть (список массивов), удалить только дубликаты. Я запустил этот код, и он все еще не работает. –

0

При использовании in, Python итерации список и проверяет на равенство с вашим элементом. Тем не менее, проверка равенства даст что-то вроде [True, False, True], которое не является ни истинным, ни ложным. Таким образом, вы не можете использовать оператор in, но вы можете имитировать его с чеком ниже

newlist = [] 

for line in lista: 
    for item in line: 
     if not any(all(item == value) for value in newlist): 
      newlist.append(item) 

По существу, с all(item==value) for value in list) вы имитирующего поведение in, и с not any, вы спросите, что ни один из чеков должно быть правдой/

+0

Он работает для удаления материала, но он не работает для того, что мне нужно. Элементы 'lista' являются кортежем, состоящим из 3 массивов, и они должны сохранять эту структуру. Таким образом, дубликат элемента - это, в основном, кортеж, содержащий те же 3 массива в том же порядке, что и другой. Я изучу ваш код и посмотрю, смогу ли я его изменить. –

0
import numpy 
from numpy import array 

lista = [(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 1.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.])), 
(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 0.])), 
(array([ 0., 0., 0.]), array([ 0., 1., 0.]), array([ 0., 0., 1.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 0.])), 
(array([ 1., 0., 0.]), array([ 0., 0., 0.]), array([ 0., 0., 1.]))] 

y = [] 

for a in lista: 
    found = 0 
    for b in y: 
     if found >= 3: 
      break 
     found = 0 
     for i in range(0,3): 
      if False in numpy.in1d(a[i], b[i]): 
       break 
      found += 1 
    if found < 3: 
     y.append(a) 

for a in y: 
    print a 

код проходит через каждый из элементов в списке и сравнивает элементы кортежей с использованием numpy.in1d(a, b). Если эти 3 элемента совпадают, элемент является дубликатом. В противном случае он добавляется к y.

0

Предполагая, что все строки имеют одинаковую длину, то следующий будет решить вашу проблему:

import numpy_indexed as npi 
npi.unique(lista) 
+0

Это будет работать с одним измерением элемента, а не с кортежами (1d), поэтому он будет выводить '[0. 1.] вместо уникальных кортежей. – TheNavigat

Смежные вопросы