скажем, у меня есть такой двумерный массив
numpy.array(
[[0,1,1.2,3],
[1,5,3.2,4],
[3,4,2.8,4],
[2,6,2.3,5]])
Я хочу сформировать массив, исключающий целые строки на основе уникальности значений последнего столбца, выбирая строку для сохранения на основе значения третьего столбца. например в этом случае я хотел бы сохранить только одну из строк с 4 в качестве последнего столбца и выбрать ту, которая имеет второстепенное значение третьего столбца, получив в результате что-то вроде этого:
array([0,1,1.2,3],
[3,4,2.8,4],
[2,6,2.3,5])
таким образом удаляя строку [1,5,3.2,4]
как лучше всего это сделать?






Мой numpy - это выход из практики, но это должно сработать:
#keepers is a dictionary of type int: (int, int)
#the key is the row's final value, and the tuple is (row index, row[2])
keepers = {}
deletions = []
for i, row in enumerate(n):
key = row[3]
if key not in keepers:
keepers[key] = (i, row[2])
else:
if row[2] > keepers[key][1]:
deletions.append(i)
else:
deletions.append(keepers[key][0])
keepers[key] = (i, row[2])
o = numpy.delete(n, deletions, axis=0)
Я значительно упростил его из своего декларативного решения, которое становилось довольно громоздким. Надеюсь, за этим легче следить; все, что мы делаем, это ведем словарь значений, которые мы хотим сохранить, и список индексов, которые мы хотим удалить.
Я буду немного точнее: алгоритмически это неправильно. Для работы мне нужно было отсортировать массив, чего я действительно хочу избежать, чтобы сократить время выполнения до O (n), что должно быть в этом решении.
Этого можно эффективно достичь в Numpy, объединив lexsort и unique следующим образом.
import numpy as np
a = np.array([[0, 1, 1.2, 3],
[1, 5, 3.2, 4],
[3, 4, 2.8, 4],
[2, 6, 2.3, 5]])
# Sort by last column and 3rd column when values are equal
j = np.lexsort(a.T)
# Find first occurrence (=smallest 3rd column) of unique values in last column
k = np.unique(a[j, -1], return_index=True)[1]
print(a[j[k]])
Это возвращает желаемый результат
[[ 0. 1. 1.2 3. ]
[ 3. 4. 2.8 4. ]
[ 2. 6. 2.3 5. ]]
Добавьте в конце свою версию с
itertools.groupby(). Это интересно.