csv の列条件に基づいて awk で平均を計算する

csv の列条件に基づいて awk で平均を計算する

次のような形式がありますcsv月全体の値がありますが、私はそれをチャンクにしました:

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,

その日の値 ($4) に基づいて最初の列 ($1) の平均を計算する必要があります。計算を簡単にするために必要であれば、日付の書式を変更できることに注意してください。

私の惨めな試みは次のようなものでした:

$ awk  '{FS=","; day=$4;value+=$1} END{ print  day,value/NR}' file
27:May:2017 2109.41

次のような出力が必要です:

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*

答え1

これをチェックしてください:

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

説明:

-F,: 区切り文字を定義します。代わりにawk 'BEGIN{FS=","}...

次に、2 つの配列を作成しdate1date24 番目のフィールドを配列のインデックス/キーとして使用し$4、最初のフィールドを$1同じ配列位置の既存の値に追加された値として使用します。

最初の行は

date1[27:May:2017]+=2415.02
++date2[27:May:2017]--> 値を 1 増加します --> 最初の行の値は 1 です

次の同じ日付(2行目)では、

date1[27:May:2017]+=2415.02 + 3465.02
++date2[27:May:2017]--> 値を 1 増加します --> 値 2 (2 行目)

同じロジックは、同じ日付を持つすべての行と、異なる日付を持つすべての行に適用されます。

最後に、forループを使用して配列のキーを反復処理しdate1(またはdate2、両方の配列でキーが同じ => $4)、key見つかったものごとにkey(= 日付 $4) を出力します。また、date1[key]値 = 同じ日付のすべての$1値の合計を値$4で割ったdate2[key]値 = 同じ日付 = 同じである見つかった行の数値カウントも出力します$4

答え2

これは、GNU データマッシュ平均化を行うには:

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

関連情報