2016-11-10 5 views
0

ich den Durchschnitt einer bestimmten Anzahl von Zeilen, in diesem Fall erhalten möchten diese Zahl durch die zweite Säule diktiert wirdDurchschnitt einer bestimmten Anzahl von Zeilen

-1 1 22.776109913596883 0.19607208141710716 
-1 1 4.2985901827923954 1.0388892840309705 
-1 1 4.642271812306717 0.96197712195674756 
-1 2 2.8032298255711794 1.5930763994471333 
-1 2 2.9358628368936479 1.5211062387604053 
-1 2 4.9987168801017106 0.8933811184867273 
1 4 2.6211673161014915 1.7037291934441456 
1 4 4.483831056393683 0.99596956735821618 
1 4 9.7189442154485732 0.4594901646050486 

Die erwartete Ausgabe

wäre
-1 1 0.732313 
-1 2 1.33585 
1 4 1.05306 

ich habe

awk '{sum+=$4} (NR%3)==0 {print $2,$3,sum/3;sum=0;}' test 

getan, die (NR%3)==0 verallgemeinern funktioniert, aber ich möchte (irgendwie) in einer Weise, dass awk erkennt, dass sich der Wert der zweiten Spalte geändert hat und daher bedeutet, dass es sich um einen neuen Durchschnitt handelt, den er berechnen muss. Zum Beispiel, die ersten drei Zeilen haben 1 als Wert in der zweiten Spalte, also einmal 1 ändert sich zu 2 dann bedeutet, dass es ein neuer Durchschnitt ist, was es berechnet werden muss.

Macht das Sinn?

Antwort

1

Versuchen Sie so etwas wie:

awk '{sum[$2] += $4; count[$2] += 1; } 
    END { for (k in sum) { print k " " sum[k]/count[k]; } }' 

Nicht getestet, aber das ist die Idee ...

Mit diesem Verfahren wird die whold Berechnung am Ende gedruckt wird; Vielleicht ist es nicht das, was du willst, wenn die Eingabe ein unendlicher Stream ist, aber nach deinem Beispiel denke ich, dass es in Ordnung sein sollte.

Wenn Sie die erste Spalte auch behalten möchten, können Sie es mit dem gleichen System perfekt machen.

0

können Sie auch versuchen versuchen dies;

awk '{array[$1" "$2]+=$4} END { for (i in array) {print i" " array[i]/length(array)}}' test | sort -n 

Test;

$ awk '{array[$1" "$2]+=$4} END { for (i in array) {print i" " array[i]/length(array)}}' test | sort -n 
-1 1 0.732313 
-1 2 1.33585 
1 4 1.05306 
Verwandte Themen