У меня есть длинный список значений (здесь ниже сокращенная версия), которые мне нужно посчитать:
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]]
Я прочитал вопросы о группировке и кластеризации, но не знаю, как их применять. Мне нужно посчитать их с некоторым заданным допуском, отслеживая, сколько раз каждый из них был найден.
Вам нужна группировка/кластеризация. Затем вы можете выбрать из большого количества похожих вопросов: 11513484 stackoverflow.com/questions/35094454 stackoverflow.com/questions/7869609 stackoverflow.com/questions/65425379 stackoverflow.com/questions/67240666
Насколько близко близко?
@RomanPerekhrest Я хочу, чтобы это был параметр для настройки как относительная ошибка (5%, 1%) или абсолютный порог (0,001, 0,00005)
Вы можете использовать кластеризацию во всех этих ссылках, чтобы сгруппировать значения, которые вы считаете похожими, а затем подсчитать каждую группу... Как это не решает вашу проблему?
@Tomerikoo, потому что, если я группирую данные, я получаю группу из 3 элементов: [9.70979, 9.7098, 9.70981], и я теряю информацию об общем количестве подсчетов. Думаю, я могу подсчитать количество элементов в каждой группе в исходном списке, но мне было интересно, есть ли более элегантный/эффективный способ сделать это.
len([9.70979, 9.7098, 9.70981])
это 3......
Вы даже можете сэкономить время и сгруппироваться после подсчета. Вы группируете по ключу и добавляете счетчики при этом
@Tomerikoo именно то, что я хочу сделать, я не знаю, как сделать ни одну из двух операций -.-"
Вы можете сгруппировать счетчики в соответствии с их ключом, как описано здесь , используя 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 Вот почему я добавил комментарий, показывающий «внутренности» groupby
. Это может немного сбить с толку в начале. Я предлагаю вам добавить несколько строк печати, чтобы понять вывод groupby
, и начать с более простых одномерных списков, чтобы понять концепцию. Затем lambda
— это просто способ сообщить различным функциям, какой элемент использовать в качестве индикатора. т.е. сортировка производится по первому элементу, группировка тоже, но с вычислением. Максимум дает список с максимальным вторым элементом, но берет первый и сумму всех вторых элементов.
1.72052
и1.71983
тоже близкие значения, почему они не добавлены? какой порог?