Давайте начнем с небольшой корректировки вашей задачи: так как исходный массив имеет значение 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)]