Подсчитать количество совпадающих событий

1

Этот вопрос связан с предыдущим вопросом, связанным здесь. Количество последовательных значений выше определенного отсечения и немного с ответом, предоставленным @kvantour

Так что в моем случае у меня есть файл вроде этого (Sample Input)

 0.34
  0.3432
  0.32
  0.35
  0.323
  0.3623
  0.345
  0.32
  0.31
  0.378
  0.34
  0.35
  0.342

Во-первых: в моем случае, если два или более последовательных значения удовлетворяют заданному обрезанию c = 0,33, я называл его B. Это задается условием m, см. Здесь: Число последовательных значений выше определенного обрезания

Во-вторых: если значение c равно 0,33, и я хочу, чтобы значения были ниже, чем c, он будет печатать 0,32 и 0,323, но я также хочу распечатать 0,35, потому что это всего лишь одно появление выше c, которое не соответствует моему правилу, как указано в m следовательно, он также будет распечатан. На это ответил @kvantour. Я назвал это F

Таким образом, в моих $ 2 состояния выглядят так: BCBCB

Поэтому я могу подсчитать количество разбитых (B) событий, таких как следующие (Sample Output)

2 #this corresponds to no. of frames in first B 
2 #this corresponds to no. of frames in second B 
4 #this corresponds to no. of frames in third B 

Есть ли способ подсчитать и распечатать нет. разбитых событий как список?

Теги:
awk

2 ответа

0
Лучший ответ

Эта проблема

Определите количество кадров в строке. Если только один кадр сломан (но предыдущий и следующий кадр хороши), это нормально, проигнорируйте это. Рамка сломана, если ее значение выше отсечки (0,33).

Решение Python

from itertools import groupby

Чтение на входе

def get_input():
    with open('input.txt') as f:
        next(f) # skip the first line
        input_list = []

Я разбиваю каждую строку на основе пробела и игнорируя номер кадра

        for line in f:
            input_list.append(float(line.split()[1]))

    return input_list

Это вспомогательная функция, которая возвращает true или False, если значение находится выше отсечки

def above_cutoff(x, cutoff):
    return x > cutoff

Здесь интересная часть. Мы группируем значения на основе того, находятся ли они выше или ниже критериев. Мы возвращаемся к группе и можем проверить, сколько в ней.

В цикле for ниже указанная above переменная будет True если группа выше обрезания. g - генератор, содержащий группу. Я просто конвертирую его в список, потому что это проще в использовании и проверяет длину.

def count_broken(input_list, cutoff):
    # returns list with number of values in a row above threshold
    state = []

    for above, g in groupby(input_list, lambda x: above_cutoff(x, cutoff)):
        group = list(g)
        print(above, group, len(group))

Если группа длиннее 1, она соответствует вашим критериям, поэтому добавьте ее длину

        if above and len(group) > 1:
            state.append(len(group))
    return state

input_list = get_input()
print(*count_broken(input_list, 0.33), sep='\n')

Операторы печати в цикле выводят это:

True [0.34, 0.3432] 2
False [0.32] 1
True [0.35] 1 # while this group is True/in state B/broken, ignore it cause it is just 1 frame.
False [0.323] 1
True [0.3623, 0.345] 2
False [0.32, 0.31] 2
True [0.378, 0.34, 0.35, 0.342] 4

Конечный результат:

2
2
4

Я основывал свое решение на принятом ответе на этот вопрос: Возьмите список, верните список True/False, основанный на последовательных повторяющихся значениях

  • 0
    Таким образом, группа - это массив, который сохраняет все эти значения как удовлетворяющие условию. Это правильно? Если нет, то как написать файл (столбец) в формате, который выводит все значения, которые удовлетворяют моему условию?
  • 0
    groupby группирует вещи относительно того, находятся ли они выше вашего порога или нет. Если они есть, above это True . При проверке длины group и проверках логического значения above , вы можете проверить , если эта group является одним вы хотите сделать что - то с.
Показать ещё 3 комментария
2

awk на помощь (с друзьями)

$ awk 'NR>1{print ($2>0.33)}' file | uniq -c | awk '$2 && $1>1{print $1}'

2
2
4

объяснение

NR>1{print ($2>0.33)} напечатайте 1 или 0, выполняется ли условие $2>0.33, пропуская первую строку заголовка.

uniq -c подсчитывает последовательные повторяющиеся значения (длина цепи)

$2 && $1>1{print $1} печатать длину цепочки, когда значение отличное от нуля (здесь оно 1), а длина больше единицы, как указано OP.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню