Как найти индекс повторов в 2d массиве? - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть 2D-массив, как мне найти индекс всех повторов в этом массиве?Например, данные выглядят так:

array([[116.366 ,  39.8673],[116.17  ,  40.2865],...[112.5628,  37.8964]]), 

, если первое и третье совпадают, второе и четвертое совпадают, тогда возвращаемое значение должно быть как [[1,3],[2,4]].

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Вот один из способов сделать это.Допустим, у вас есть:

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

Вы можете превратить все внутренние списки в строки:

l = list(map(str,l_))

Позволяет искать индексы дублированных списков, используя np.in1dв сочетании с np.flatnonzero:

dup = {tuple(np.flatnonzero(np.in1d(l,i))) for i in l}

Обратите внимание, что np.in1d(l,i)) повторяется для каждой «строки» в списке, и, таким образом, один и тот же результат повторяется столько раз, сколько существуетМатчи.Создание set из tuples решит эту проблему, избегая дублирования.

Наконец, чтобы отфильтровать недвойственные списки (кортежи из одного элемента), вы можете сделать:

list(filter(lambda x: len(x) > 1, dup))

[(0, 1), (3, 4, 5)]
0 голосов
/ 15 декабря 2018

Давайте начнем с небольшой корректировки вашей задачи: так как исходный массив имеет значение 2-мерное , каждый элемент имеет два индекса, поэтому, если элемент встречается несколько раз, результатдля этого элемента должен быть список пар (строка / столбец) - какие элементы имеют это значение.

А что касается кода, давайте начнем с импорта и созданияисходный массив:

import numpy as np
import pandas as pd

tbl = np.array([[116.3, 39.8], [116.1, 40.2],  [40.2, 116.3], [112.5, 37.8]])

Как видите, у нас есть 4 строки и 2 столбца, где 116.3 и 40.2 встречаются дважды.

Затем мы должны сгенерировать данные дляDataFrame (значение и индексы для каждого элемента).Для этого мы можем использовать функцию np.nditer:

tbl2 = []
it = np.nditer(tbl, flags=['multi_index'])
while not it.finished:
    tbl2.append([float(it[0]), it.multi_index])
    it.iternext()

Требуется явное приведение (согласно вашим данным к float), поскольку в противном случае итератор возвращает 0-мерные массивы NumPy, которыене хэшируемый, что вызывает проблемы позже.

Затем мы создаем DataFrame с правильными именами столбцов (элемент и его индексы):

df = pd.DataFrame(data=tbl2, columns=['elem', 'indices'])

И последний пункт - создать результат:

df[df.duplicated(subset=['elem'], keep=False)]\
    .groupby('elem')['indices'].apply(list)

Выходные данные (для приведенных выше данных):

elem
40.2     [(1, 1), (2, 0)]
116.3    [(0, 0), (2, 1)]
Name: indices, dtype: object

На самом деле получается Pandas Series с ключом с именем elem (значение элемента), а значением является список кортежей - индексов конкретного элемента в исходном массиве.

Если вас интересуют только индексов неуникальных элементов, сохраните приведенный выше результатнапример, в переменной result и добавьте:

[y for x in result for y in x]

Тогда результат будет:

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