[英]Find the probability in 2nd column for a selection in 1st column
我有两列如下
ifile.dat
1 10
3 34
1 4
3 32
5 3
2 2
4 20
3 13
4 50
1 40
2 20
5 2
我想计算第一列中某些选择的第二列中的概率。
ofile.dat
1-2 0.417 #Here 1-2 means all values in 1st column ranging from 1 to 2;
#0.417 is the probability of corresponding values in 2nd column
# i.e. count(10,4,2,40,20)/total = 5/12
3-4 0.417 #count(34,32,20,13,50)/total = 5/12
5-6 0.167 #count(3,2)/total = 2/12
同样,如果我选择了 3 个数字的选择范围,那么期望的输出将是
ofile.dat
1-3 0.667
4-6 0.333
RavinderSingh13 和 James Brown 给出了不错的脚本(请参阅答案),但这些脚本不适用于第一列中大于 10 的值。
ifile2.txt
10 10
30 34
10 4
30 32
50 3
20 2
40 20
30 13
40 50
10 40
20 20
50 2
~
EDIT2:考虑到 OP 编辑过的样本,您可以尝试以下操作吗? 我已经用 OP 的第一个和最新的编辑样本成功地对其进行了测试,并且它们都可以正常工作。
还有一件事,我制作了这个解决方案,这样一个“角落案例”可能会留下打印元素,以防它在最后一行没有跨越范围值。 就像 OP 的第一个示例,其中range=2
但最大值为5
因此不会在此处留下 5。
sort -n Input_file |
awk -v range="2" '
!b[$1]++{
c[++count]=$1
}
{
d[$1]=(d[$1]?d[$1] OFS:"")$2
tot_element++
till=$1
}
END{
for(i=1;i<=till;i++){
num+=split(d[i],array," ")
if(++j==range){
start=start?start:1
printf("%s-%s %.02f\n",start,i,num/tot_element)
start=i+1
j=num=""
delete array
}
if(j!="" && i==till){
printf("%s-%s %.02f\n",start,i,num/tot_element)
}
}
}
'
输出如下。
1-10 0.25
11-20 0.17
21-30 0.25
31-40 0.17
41-50 0.17
编辑:如果您的 Input_file 没有第二列,请尝试以下操作。
sort -k1 Input_file |
awk -v range="1" '
!b[$1]++{
c[++count]=$1
}
{
d[$1]=(d[$1]?d[$1] OFS:"")$0
tot_element++
till=$1
}
END{
for(i=1;i<=till;i+=(range+1)){
for(j=i;j<=i+range;j++){
num=split(d[c[j]],array," ")
total+=num
}
print i"-"i+range,tot_element?total/tot_element:0
total=num=""
}
}
'
您能否尝试使用所示示例进行以下,编写和测试。
sort -k1 Input_file |
awk -v range="1" '
!b[$1]++{
c[++count]=$1
}
{
d[$1]=(d[$1]?d[$1] OFS:"")$2
tot_element++
till=$1
}
END{
for(i=1;i<=till;i+=(range+1)){
for(j=i;j<=i+range;j++){
num=split(d[c[j]],array," ")
total+=num
}
print i"-"i+range,tot_element?total/tot_element:0
total=num=""
}
}
'
如果您不必包含任何0
值,请尝试以下操作。
sort -k1 Input_file |
awk -v range="1" '
!b[$1]++{
c[++count]=$1
}
{
d[$1]=(d[$1]!=0?d[$1] OFS:"")$2
tot_element++
till=$1
}
END{
for(i=1;i<=till;i+=(range+1)){
for(j=i;j<=i+range;j++){
num=split(d[c[j]],array," ")
total+=num
}
print i"-"i+range,tot_element?total/tot_element:0
total=num=""
}
}
'
其他:
$ awk '
BEGIN {
a[1]=a[2]=1 # define the groups here
a[3]=a[4]=2 # others will go to an overflow group 3
}
{
b[(($1 in a)?a[$1]:3)]++ # group 3 defined here
}
END { # in the end
for(i in b) # loop all groups in no particular order
print i,b[i]/NR # and output
}' file
输出
1 0.416667
2 0.416667
3 0.166667
更新。 另一个带有范围配置文件的 awk。 $1 是范围的开始,$2 是结束,$3 是组名:
1 3 1-3
4 9 4-9
10 30 10-30
40 100 40-100
awk程序:
$ awk '
BEGIN {
OFS="\t"
}
NR==FNR {
for(i=$1;i<=$2;i++)
a[i]=$3
next
}
{
b[(($1 in a)?a[$1]:"others")]++ # the overflow group is now called "others"
}
END {
for(i in b)
print i,b[i]/NR
}' rangefile datafile
将两个数据集连接在一起的输出(以及通过管道传输到sort -n
awk 输出):
1-3 0.285714
4-9 0.142857
10-30 0.285714
40-100 0.142857
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.