Удаление совпадающих элементов из двух массивов - PullRequest
2 голосов
/ 14 октября 2019

Рассмотрим два отсортированных массива numpy:

import numpy as np

a = np.array([1,2,4,4,6,8,10,10,21])
b = np.array([3,3,4,6,10,18,22])

Как мне: 1. Найти элементы, которые появляются в обоих списках, и 2. Удалить только один экземпляр этогопоявление из каждого списка.

То есть вывод должен быть:

a = [1,2,4,8,10,21]

b = [3,3,18,22]

Таким образом, даже если есть дубликаты, удаляется только один экземпляр. Однако, если списки

c = np.array([1,2,4,4,6,8,10,10,10,21])
d = np.array([3,3,4,6,10,10,18,22])

, я ожидаю получить новые выходные данные:

c = [1,2,4,8,10,21]

d = [3,3,18,22]

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

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

Ответы [ 6 ]

3 голосов
/ 14 октября 2019

Вы можете использовать collection.Counter :

from collections import Counter

import numpy as np

a = np.array([1, 2, 4, 4, 6, 8, 10, 10, 21])
b = np.array([3, 3, 4, 6, 10, 18, 22])

ca = Counter(a)
cb = Counter(b)

result_a = sorted((ca - cb).elements())
result_b = sorted((cb - ca).elements())

print(result_a)
print(result_b)

Выход

[1, 2, 4, 8, 10, 21]
[3, 3, 18, 22]

Возвращает тот же результат для (как и ожидалось)):

a = np.array([1, 2, 4, 4, 6, 8, 10, 10, 10, 21])
b = np.array([3, 3, 4, 6, 10, 10, 18, 22])
1 голос
/ 14 октября 2019

Вы можете найти индексы первых появлений пересекающихся предметов, используя np.searchsorted, как показано ниже, а затем удалить их, используя функцию np.delete():

In [58]: intersect = a[np.in1d(a, b)]
In [59]: mask1 = np.searchsorted(a, intersect)

In [60]: mask2 = np.searchsorted(b, intersect)

In [61]: np.delete(a, mask1)
Out[61]: array([ 1,  2,  4,  8, 10, 21])

In [62]: np.delete(b, mask2)
Out[62]: array([ 3,  3, 18, 22])
0 голосов
/ 14 октября 2019

Вот примерный подход:

import numpy as np

a = np.array([1,2,4,4,6,8,10,10,21])
b = np.array([3,3,4,6,10,18,22])

# join and sort (with Tim sort this should be O(n))
ab = np.concatenate([a,b])
i = ab.argsort(kind="stable")
abo = ab[i]

# mark 1st of each group of equal values
d = np.flatnonzero(np.diff(abo,prepend=abo[0]-1,append=abo[-1]+1))
# mark sorted total by origin (a -> False, b -> True)
ig = i>=len(a)
# compare origins of first and last of each group of equal values
# if they are different mark for deletion
dupl = ig[d[:-1]] ^ ig[d[1:]-1]

# finally, delete
ar = np.delete(a,i[d[:-1][dupl]])
br = np.delete(b,i[d[1:][dupl]-1]-len(a))

# inspect
ar
array([ 1,  2,  4,  8, 10, 21])
br
array([ 3,  3, 18, 22])
0 голосов
/ 14 октября 2019

Использование для циклов:

import numpy as np

a = np.array([1,2,4,4,6,8,10,10,21])
b = np.array([3,3,4,6,10,18,22])

for i, val in enumerate(a):
    if val in b:
        a = np.delete(a, np.where(a == val)[0][0])
        b = np.delete(b, np.where(b == val)[0][0])

for i, val in enumerate(b):
    if val in a:
        a = np.delete(a, np.where(a == val)[0][0])
        b = np.delete(b, np.where(b == val)[0][0])

print(a)
print(b)

Выходы:

[1,2,4,8,10,21]
[3,3,18,22]
0 голосов
/ 14 октября 2019

Я не уверен на 100%, что вы хотите сделать, основываясь на этом вопросе, но я смог продублировать вывод, используя описанные методы.

import numpy as np

# List of b that are not in a
a = np.array([1,2,4,4,6,8,10,10,21])
b = np.array([3,3,4,6,10,18,22])
newb = [x for x in b if x not in a]
print(newb)

# REMOVE ONE DUPLICATED ELEMENT FROM LIST
import collections
counter=collections.Counter(a)
print(counter)
newa = list(a)
for k,v in counter.items():
    if v > 1:
        newa.remove(k)
print(newa)
0 голосов
/ 14 октября 2019

Если не возражаете против многословия:

import numpy as np

a = np.array([1,2,4,4,6,8,10,10,21])
b = np.array([3,3,4,6,10,18,22])

common_values = set(a) & set(b)

a = a.tolist()
b = b.tolist()

for value in common_values:
    a.remove(value)
    b.remove(value)

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