Eu tenho o seguinte csv
formato.Existem vals do mês inteiro, mas eu dividi:
2415.02,2203.35,00:17,25:May:2017,
3465.02,2203.35,01:17,25:May:2017,
2465.02,2203.35,12:17,26:May:2017,
465.02,2203.35,13:17,26:May:2017,
245.02,2203.35,14:17,26:May:2017,
2465.02,2203.35,05:17,26:May:2017,
2865.02,2203.35,06:17,27:May:2017,
2490.12,2203.35,07:17,27:May:2017,
Preciso calcular a média da primeira coluna ($1) com base nos valores daquele dia ($4). Observe que posso reformatar a data, se for necessário para facilitar o cálculo.
Minha tentativa miserável foi esta:
$ awk '{FS=","; day=$4;value+=$1} END{ print day,value/NR}' file
27:May:2017 2109.41
Eu preciso de uma saída como esta:
Average for 25th May is *average_for_25th_day*
Average for 27th May is *average_for_26th_day*
Average for 28th May is *average_for_27th_day*
Responder1
Veja isso:
awk -F, '{date1[$4]+=$1;++date2[$4]}END{for (key in date1) print "Average of",key,"is",date1[key]/date2[key]}' file
Average of 27:May:2017 is 2677.57
Average of 26:May:2017 is 1410.02
Average of 25:May:2017 is 2940.02
Explicação:
-F,
: Define o delimitador. Alternativamente poderia serawk 'BEGIN{FS=","}...
Em seguida, criamos dois arrays date1
e date2
nos quais usamos o 4º campo $4
como índice/chave do array e o primeiro campo $1
como valor adicionado ao valor existente da mesma posição do array.
Então para a primeira linha teríamos
date1[27:May:2017]+=2415.02
++date2[27:May:2017]
-> aumenta o valor em 1 -> valor 1 para a primeira linha
Para a próxima mesma data (linha 2) teríamos
date1[27:May:2017]+=2415.02 + 3465.02
++date2[27:May:2017]
-> aumenta o valor em 1 -> valor 2 (segunda linha)
A mesma lógica se estende a todas as linhas com a mesma data e também a todas as datas diferentes.
No final, usamos um for
loop para iterar pelas chaves do array date1
(ou date2
- as chaves são iguais em ambos os arrays => $4
) e para cada key
encontrado imprimimos key
(= a data $4) e também imprimimos o date1[key]
valor = soma de todos $1
os valores para a mesma data $4
, divididos por date2[key]
valor = contagem numérica das linhas encontradas com a mesma data = mesma $4
.
Responder2
Aqui está uma variante, usandoConjunto de dados GNUpara fazer a média:
datamash -t, groupby 4 mean 1 < file |
awk -F'[,:]' '{printf "Average for %dth %s is %f\n", $1,$2,$4}'
Average for 25th May is 2940.020000
Average for 26th May is 1410.020000
Average for 27th May is 2677.570000