Вычисление значения коэффициента в строке, содержащей двоичные числа 0 и 1

У меня есть файл данных, содержащий более 2000 строк и 45001 столбец.

Первый столбец на самом деле представляет собой «строку», которая объясняет тип данных.

Начните со столбца № 2 до столбца № 45001, данные представлены в виде

"1"

or

"0"

Например, шаблон данных в строке

(0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0)

Общее количество данных равно 25. В этой строке данных есть 5 подгрупп, которые состоят только из числа «1», например. (11 111 1111 1 111 ). «0» между подгруппами считаются «разделителями». Сумма всех «1» = 13.

Я хотел бы рассчитать соотношение

(сумма всех «1» / общее количество подгрупп, составленных только «1»)

То есть

(13/5).

Я попытался использовать этот код для вычисления суммы всех «1»;

awk -F '0' '{print NF}' < inputfile.in

Это дает значение 13.

Но я не знаю, как пойти дальше, чтобы рассчитать соотношение, которое я хочу. Я не знаю, как найти количество подгрупп в каждой строке, потому что количество вхождений «1» и «0» случайно.

Желание получить некоторую помощь, чтобы решить эту проблему.

Оцените любую помощь заранее.


person Vijay    schedule 15.03.2015    source источник
comment
разместить точный ввод. есть ли пробелы до и после ти цифр?   -  person Avinash Raj    schedule 15.03.2015
comment
Это пример данных [BMR_10@O24-BMR_6@O13-H13 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1]. Первый столбец — это строка, а остальные — данные только из одной строки. Я не могу показать реальный файл, потому что размер около 5 МБ.   -  person Vijay    schedule 15.03.2015


Ответы (2)


Мне из описания непонятно, какой формат входного файла. Предположим, что ввод выглядит так:

$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0

Чтобы подсчитать количество единиц и количество групп единиц и взять их соотношение:

$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; print s1/s2}' file
2.6

Обновление: обработка всех нулей

Предположим, что в одной из строк файла все нули:

$ cat file
0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Для второй строки обе суммы равны нулю, что привело бы к ошибке деления на ноль. Мы можем избежать этого, добавив оператор if, который будет печатать отношение, если оно существует, или 0/0, если оно не существует:

if (s2>0)print s1/s2; else print s1"/"s2

Полный код теперь:

$ awk '{f=0;s1=0;s2=0;for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}; if (s2>0)print s1/s2; else print s1"/"s2}' file
2.6
0/0

Как это работает

В коде используются три переменные. f — это флаг, который равен true (1), если мы в данный момент находимся в группе единиц, и false (0) в противном случае. s1 - это количество единиц в строке. s2 — количество групп единиц в строке.

  • f=0;s1=0;s2=0

    В начале каждой строки мы инициализируем переменные.

  • for (i=2;i<=NF;i++){s1+=$i;if ($i && !f)s2++;f=$i}

    Мы перебираем каждое поле в строке, начиная с поля 2. Если поле содержит 1, мы увеличиваем счетчик s1. Если поле равно 1 и является началом новой группы, мы увеличиваем s2.

  • if (s2>0)print s1/s2; else print s1"/"s2}

    Если мы встретили хотя бы один, мы выводим отношение s1/s2. В противном случае мы печатаем 0/0.

person John1024    schedule 15.03.2015
comment
Но, сэр, есть строки, в которых данные содержат строку со всеми нулями, например (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0). Поэтому, когда я пытаюсь, я получаю сообщение об ошибке ([vijay@glycogpu process-rawData]$ ./find-sum-and-ratio.sh 947 17 55.7059 awk: (FILENAME=outPut3.dat FNR=2) фатальный: деление на ноль попытка). Возможно ли это преодолеть? - person Vijay; 15.03.2015
comment
@ Виджай, хорошо. В обновленном ответе есть код для этого. - person John1024; 15.03.2015
comment
Это не даст правильных данных, если вы добавите номер столбца 1 с информацией о данных. ОП: Start from column #2, up to column #45001, the data is reprsented as 0 or 1 - person Jotne; 15.03.2015

person    schedule
comment
Это не дает правильных данных, если последний столбец содержит 1. Попробуйте, например, echo data 0 1 1 | awk -F1 '{gsub(/ +/,"");n=split($0,a,"[^1]+")-2;print (n?(NF-1)/n:"0")}'. Результат должен быть 2, код возвращает 0. - person John1024; 15.03.2015
comment
@John1024 John1024 Это также не удастся, если столбец 1 информационный столбец содержит 1, как в комментариях ОП. Постараюсь исправить. - person Jotne; 15.03.2015
comment
Обновлен новыми примерными данными для правильного расчета. - person Jotne; 15.03.2015