Как классифицировать значения из одного списка на основе пороговых значений в другом? - PullRequest
2 голосов
/ 05 апреля 2019

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

input:
Values = [9999, 3000, 400, 9999, 1000] - it is variably long due to input data
Threshold = [10000, 5000, 1500, 800, 0] - also will be changed, so have to be variable - but always sorted descending to 0

Expected output (categories' numbers should be based on index):
cat = [0,1,3,0,2]

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

val_cat = []
thres_len = len(Threshold)
for item in Values:
     for vis in range(0,thres_len - 1):
          if Threshold[vis+1] < int(item) <= Threshold[vis]:
             val_cat = val_cat + [vis]
          else:
             pass

Этот способ не является ни питоническим, ни функциональным, но лучше всего я мог бы попробовать, так как я изучал только основы VB несколько лет назад.

Спасибо за вашу помощь! Я считаю, что для этого сообщества это кусок пирога: -)

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Если вы действительно хотите сделать это списком, вот вам:

cat = [next(i-1 for i,t in enumerate(Threshold) if t <= v) for v in Values]

Но вы ожидаете этого:

  • Последний порог Threshold[-1] должен быть меньшечем все в Values (т. е. абсолютная нижняя граница)
  • Это не быстро: O (mn) для m размером Values и n размером Threshold.Более эффективный алгоритм будет заключаться в бинарном поиске по Threshold для каждого значения

. Поэтому вы можете захотеть реализовать собственную функцию для замены next() выше, чтобы решить две вышеуказанные проблемы..

0 голосов
/ 05 апреля 2019
Модуль

bisect может использоваться для поиска индексов:

import bisect

Values = [9999, 3000, 400, 9999, 1000]
Threshold = [10000, 5000, 1500, 800, 0]

reversed_Threshold = list(reversed(Threshold))
len_Threshold = len(Threshold)

cat = [len_Threshold - bisect.bisect_left(reversed_Threshold, value) - 1 for value in Values]
print(cat)

Требуется сортировка порога в прямом порядке.Но сложность O (len (Значения) * log (len (Порог))).

...