adicione e calcule a porcentagem

1

Eu tenho duas colunas de dados, eu quero adicionar o número de registros repetidos na coluna A e, em seguida, calcular o número de contagens na coluna B e, em seguida, calcular a porcentagem de contagens. Exemplo:

494   1
494
494
494   1
500
500   1
500
501
501
501  1
501

Para 494, há 4 registros e 2 registros, então eu gostaria de calcular 2/4 = 0,50 e assim por diante.

    
por Lori 12.10.2017 / 21:22

2 respostas

2

Como uma linha única, este exemplo de awk é bastante complicado.

{
  if (A!=$1) {   # This section has a different A-column
    if (a) {       # If a>0, then it is not the beginning
      print A,b/a  # Print result
    }
    A=$1;          # Re-init variables
    a=0;
    b=0
  }
  ++a;
  b += $2 ? 1 : 0
}

Para executar isso, coloque o script awk em frac-calc e os números em number e execute-os:

( cat number; echo ) | awk -E frac-calc

A saída seria:

494 0.5
500 0.333333
501 0.25

A razão pela qual o echo é necessário, é que ele garante que o resultado do último bloco (501) seja impresso, já que a coluna A é diferente.

Também pode ser um longo one-liner:

( cat number; echo ) | awk '{if(A!=$1){if(a){print A,b/a}A=$1;a=0;b=0}++a;b+=$2?1:0}'

Editar : com o uso de END e sem echo , conforme mencionado nos comentários:

{
  if (A!=$1) {   # This section has a different A-column
    if (a) {       # If a>0, then it is not the beginning
      print A,b/a  # Print result
    }
    A=$1;          # Re-init variables
    a=0;
    b=0
  }
  ++a;
  b += $2 ? 1 : 0
}
END {
      print A,b/a  # Print result
}

E chame:

awk -E frac-calc number

O revestimento é um pouco mais longo:

awk '{if(A!=$1){if(a){print A,b/a}A=$1;a=0;b=0}++a;b+=$2?1:0}END{print A,b/a}' number
    
por 13.10.2017 / 01:01
0

Primeira versão - o array bidimensional é usado.

gawk '
BEGIN {
    PROCINFO["sorted_in"] = "@ind_num_asc";
}
{
    arr[$1][0]++;
    arr[$1][1] += $2;
}
END {
    for(i in arr) {
        print i, arr[i][1] / arr[i][0];
    }
}' input.txt

A linha PROCINFO["sorted_in"] = "@ind_num_asc"; é explicada aqui - Usando pedidos de varredura de matriz predefinidos .

Nesse caso, ele pode ser substituído pelo piping da saída gawk para o comando sort -n :

gawk '
{
    arr[$1][0]++;
    arr[$1][1] += $2;
}
END {
    for(i in arr) {
        print i, arr[i][1] / arr[i][0];
    }
}' input.txt | sort -n

Segunda versão - variante mais otimizada, sem matriz.

gawk '
NR == 1 { 
    record = $1;
}
record != $1 {
    print record, tallies / cnt;    
    record = $1;
    cnt = 0;
    tallies = 0;
}
{
    cnt++;
    tallies += $2;
}
END {
    print record, tallies / cnt;    
}' input.txt

Saída:

494 0.5
500 0.333333
501 0.25
    
por 13.10.2017 / 01:59