/ / Bash Awk: mediana sobre janelas com posições de início e parada - bash, awk

Bash Awk: Mediana sobre janelas com posições de início e parada - bash, awk

Eu tenho um arquivo de texto que se parece com abaixo. A primeira coluna é a localização, a segunda é a posição e a terceira é o valor.

1 10 200
1 11 150
1 12 300
2 13 400
2 14 100
2 15 250
3 16 200
3 17 200
3 18 350
3 19 150
...

Gostaria de calcular a mediana do campo de valor em uma determinada janela. Por exemplo, digamos um tamanho de janela de 4 linhas. Abaixo está o resultado esperado para os dados de amostra acima:

1 2 10 13 250
2 3 14 17 200
...

Para cada janela (4 linhas), o primeiro valor(dentro da janela) da primeira coluna, é relatado o último valor (dentro da janela) da primeira coluna, o primeiro valor da segunda coluna, o último valor da segunda coluna e a mediana da terceira coluna.

Eu tenho parcialmente trabalhando. O script abaixo imprime a última posição da coluna 1, a última posição da coluna 2 e a média.

win=4
cat file.txt | awk -v win="$win" "{sum+=$3} (NR%win)==0 {print $1,$2,sum/win;sum=0}"

2 13 262.5
3 17 187.5
...

Como obtenho as posições iniciais em cada janela e mediana?

Respostas:

2 para resposta № 1
$ awk "{r=(NR-1)%4; a[r]=$3}
r==0{f1=$1; s1=$2}
r==3{asort(a); print f1,$1,s1,$2,(a[2]+a[3])/2; delete a}" file

1 2 10 13 250
2 3 14 17 200

observe que a exclusão não é realmente necessária, pois os valores são substituídos a cada cálculo da janela ...

você pode parametrizar o tamanho da janela, precisa lidar com ímpares / pares

$ awk -v w=5 "{r=(NR-1)%w; a[r]=$3}
r==0{f1=$1; s1=$2}
r==(w-1){asort(a);
print f1,$1,s1,$2,(w%2?a[int(w/2)+1]:(a[w/2]+a[w/2+1])/2);
delete a}" file

1 2 10 14 200
2 3 15 19 200

não lida se a última janela não tiver o tamanho completo