计算包含二进制数“0”和“1”的行内的比率值
Calculating ratio value within a line which contain binary numbers "0" & "1"
我有一个包含超过 2000 行和 45001 列的数据文件。
第一列实际上是一个"string",它解释了数据类型。
从第 2 列开始,直到第 45001 列,数据表示为
"1"
或
"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"s e.g. (11
111
1111
1
111
). The "0"s in between the subgroups are assumed as "定界符组成。所有“1”的总数为 = 13。
我想计算
的比例
(total of all "1"s / total of number of sub-groups made only by "1"s)
也就是
(13/5).
我尝试使用这段代码来计算所有“1”的总数;
awk -F '0' '{print NF}' < inputfile.in
这给出了值 13。
但我不知道如何进一步计算我想要的比率。
我不知道如何找到每行中的子组数,因为“1"s and "0”的出现次数是随机的。
希望得到一些帮助来解决这个问题。
提前感谢任何帮助。
从描述中我不清楚输入文件的格式是什么。假设输入看起来像:
$ 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
统计1的个数和1的组数并求其比值:
$ 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
是一个标志,如果我们当前在一组中,则为真 (1),否则为假 (0)。 s1
是线上的个数。 s2
是直线上1组的个数
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
.
这里有一个 awk
可以满足您的需求:
cat file
data 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
data 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
data 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
data 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
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
data 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1
awk '{="";[=11=]="0 "[=11=]" 0";t=split([=11=],b,"1")-1;gsub(/ +/,"");n=split([=11=],a,"[^1]+")-2;print (n?t/n:0)}' t
2.6
0
25
11
5.5
3
我有一个包含超过 2000 行和 45001 列的数据文件。
第一列实际上是一个"string",它解释了数据类型。
从第 2 列开始,直到第 45001 列,数据表示为
"1"
或
"0"
例如一行数据的格式为
(0 0 0
1 1
01 1 1
01 1 1 1
0 0 01
0 01 1 1
0 0)
数据总数为25条,在这一行数据中,有5个分组,仅由数字“1"s e.g. (11
111
1111
1
111
). The "0"s in between the subgroups are assumed as "定界符组成。所有“1”的总数为 = 13。
我想计算
的比例(total of all "1"s / total of number of sub-groups made only by "1"s)
也就是
(13/5).
我尝试使用这段代码来计算所有“1”的总数;
awk -F '0' '{print NF}' < inputfile.in
这给出了值 13。
但我不知道如何进一步计算我想要的比率。 我不知道如何找到每行中的子组数,因为“1"s and "0”的出现次数是随机的。
希望得到一些帮助来解决这个问题。
提前感谢任何帮助。
从描述中我不清楚输入文件的格式是什么。假设输入看起来像:
$ 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
统计1的个数和1的组数并求其比值:
$ 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
是一个标志,如果我们当前在一组中,则为真 (1),否则为假 (0)。 s1
是线上的个数。 s2
是直线上1组的个数
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
.
这里有一个 awk
可以满足您的需求:
cat file
data 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
data 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
data 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
data 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
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
data 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1
awk '{="";[=11=]="0 "[=11=]" 0";t=split([=11=],b,"1")-1;gsub(/ +/,"");n=split([=11=],a,"[^1]+")-2;print (n?t/n:0)}' t
2.6
0
25
11
5.5
3