Подсчет элементов с допуском

У меня есть длинный список значений (здесь ниже сокращенная версия), которые мне нужно посчитать:

ed = [ 0.52309  ,  3.1443  , 16.5789  , 24.0643  ,  9.70981 ,  1.71983 ,
       16.3453  , 14.1901  , 22.0353  ,  1.71983 , 15.0469  , 13.98    ,
       11.4753  , 32.7859  ,  9.7098  ,  6.36272 ,  3.2058  ,  1.46917 ,
        6.36271 , 11.5869  ,  1.72052 ,  6.32043 ,  1.72052 ,  1.72052 ,
        5.37679 ,  3.15279 ,  9.70979 ,  1.72052 ,  3.44035 ,  2.15729 ,
       12.0049  ]

и что я считаю с:

cnt = Counter(ed)
edlist = [list(i) for i in cnt.items()]

список, который я получаю, имеет очень похожие значения среди других

[[1.72052, 60], [1.71983, 34], [6.36271, 16], [9.7098, 14],[9.70979, 5], [0.52309, 3], [9.70981, 3]]

которые я хотел бы сложить вместе в пределах заданного допуска. Например

9.7098 has 16 counts
9.70981 has 3 counts
9.70979 has 5 counts

Я хотел бы добавить их все вместе к элементу с наибольшим количеством, и я не уверен, есть ли для этого функция, позволяющая сделать это с некоторой абсолютной или относительной ошибкой. То, что я хотел бы получить, это

[[1.72052, 60], [1.71983, 34], [6.36271, 16], [9.7098, 22], [0.52309, 3]]

Я прочитал вопросы о группировке и кластеризации, но не знаю, как их применять. Мне нужно посчитать их с некоторым заданным допуском, отслеживая, сколько раз каждый из них был найден.

1.72052 и 1.71983 тоже близкие значения, почему они не добавлены? какой порог?
RomanPerekhrest 16.01.2023 09:51

Вам нужна группировка/кластеризация. Затем вы можете выбрать из большого количества похожих вопросов: 11513484 stackoverflow.com/questions/35094454 stackoverflow.com/questions/7869609 stackoverflow.com/questions/65425379 stackoverflow.com/questions/67240666

tevemadar 16.01.2023 09:55

Насколько близко близко?

Pingu 16.01.2023 09:56

@RomanPerekhrest Я хочу, чтобы это был параметр для настройки как относительная ошибка (5%, 1%) или абсолютный порог (0,001, 0,00005)

saimon 16.01.2023 10:08

Вы можете использовать кластеризацию во всех этих ссылках, чтобы сгруппировать значения, которые вы считаете похожими, а затем подсчитать каждую группу... Как это не решает вашу проблему?

Tomerikoo 16.01.2023 10:30

@Tomerikoo, потому что, если я группирую данные, я получаю группу из 3 элементов: [9.70979, 9.7098, 9.70981], и я теряю информацию об общем количестве подсчетов. Думаю, я могу подсчитать количество элементов в каждой группе в исходном списке, но мне было интересно, есть ли более элегантный/эффективный способ сделать это.

saimon 16.01.2023 10:36
len([9.70979, 9.7098, 9.70981]) это 3......
Tomerikoo 16.01.2023 10:37

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

Tomerikoo 16.01.2023 10:37

@Tomerikoo именно то, что я хочу сделать, я не знаю, как сделать ни одну из двух операций -.-"

saimon 16.01.2023 10:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
9
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Затем просуммируйте количество каждой группы и добавьте ее в окончательный список:

from itertools import groupby

l = [[1.72052, 60], [1.71983, 34], [6.36271, 16], [9.7098, 14], [9.70979, 5], [0.52309, 3], [9.70981, 3]]
l.sort(key=lambda x: x[0])

tolerance = 0.001

res = []
for key, group in groupby(l, lambda x: int(x[0]*(1/tolerance))):
    # for example: key = 9709, group = [[9.70979, 5], [9.7098, 14], [9.70981, 3]]
    group = list(group)
    res.append([max(group, key=lambda x: x[1])[0], sum(x[1] for x in group)])

print(res)

В основном это игра с lambda с использованием ключа или счета в качестве key для различных функций.


В качестве альтернативы вы можете сгруппировать сами данные (а не счетчики), а счетчик - это размер каждой группы:

from itertools import groupby

l = [0.52309, 3.1443, 16.5789, 24.0643, 9.70981, ...]
l.sort()

tolerance = 0.001

res = []
for key, group in groupby(l, lambda x: int(x*(1/tolerance))):
    res.append([key*tolerance, len(list(group))])

print(res)

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

Это работало отлично после некоторых незначительных правок. Для меня это что-то вроде черного ящика, поэтому, думаю, мне нужно изучить лямбда-функцию, чтобы иметь возможность использовать ее.

saimon 16.01.2023 11:39

@saimon Вот почему я добавил комментарий, показывающий «внутренности» groupby. Это может немного сбить с толку в начале. Я предлагаю вам добавить несколько строк печати, чтобы понять вывод groupby, и начать с более простых одномерных списков, чтобы понять концепцию. Затем lambda — это просто способ сообщить различным функциям, какой элемент использовать в качестве индикатора. т.е. сортировка производится по первому элементу, группировка тоже, но с вычислением. Максимум дает список с максимальным вторым элементом, но берет первый и сумму всех вторых элементов.

Tomerikoo 16.01.2023 12:04

Другие вопросы по теме