Эффективный подсчет предметов в больших списках Python - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть два очень больших списка Python, которые выглядят так:

List A: [0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,4.........]
List B: [0,0,0,0,0,0,2,2,2,2,3,3,4,4.........]

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

Теперь мне нужно рассчитать для каждого значения (0,1,2 .. 100 ) соотношение: вхождения в списке A / вхождения в списке B. И поскольку это значение не всегда возможно, я решил вычислять это значение только в том случае, если в каждом списке более 5 вхождений значения, и если это условие не соответствует действительности, затем объединить вхождения предыдущих значений и дать одинаковые коэффициенты для комбинированных значений, если это условие правильный. Например, для приведенных выше списков я хочу создать серию, которая выглядит следующим образом:

0 : 7/6=1.166 
1 : 9/6 = 1.5
2 : 9/6 = 1.5
3 : 9/6 = 1.5
.
.
.
100 : some_number

1 Ответ

0 голосов
/ 06 сентября 2018

Вы можете использовать Counter для подсчета вхождений и takewhile для удовлетворения вашего требования остановиться на 100.

Вместо того, чтобы отбрасывать значения, которых нет в списке b, обратите внимание, как я использовал nan.

from collections import Counter
from itertools import takewhile

def get_ratios(a, b, max_=None, min_count=0):
    if max_ is not None:
        a = takewhile(lambda x: x <= max_, a)
        b = takewhile(lambda x: x <= max_, b)

    count_a, count_b = Counter(a), Counter(b)

    return {k: float('nan') if not count_b[k] else count_a[k] / count_b[k]
            for k in set(count_a) | set(count_b)
            if count_a[k] >= min_count <= count_b[k]}

Пример

a = [1, 1, 1, 2, 3, 101]
b = [1, 1, 2, 2, 4, 101]

print(get_ratios(a, b, max_=100))

выход

{ 1: 1.5,
  2: 0.5,
  3: nan,
  4: 0.0 }

Чтобы игнорировать некоторые недопредставленные значения, вы можете установить min_count на 5, как указано в вашем вопросе.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...