列的平均值并将其导出到另一列中

列的平均值并将其导出到另一列中

我有一个如下所示的 txt 文件(这张图片来自它的 .csv 版本)。我喜欢做的是取月份的平均值(从第 7 列到第 10 列)并将其导出到新列。但它只给了我一个平均数。

OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),January,February,March,April,May,June,July,August,September,October,November,December
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.93,86.84,85.26,88.22,89.36,89.8,88.52,90.42,88.74,89.06,91.16,91.36
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,63.92,60.44,58.63,65.68,75.97,85.7,84.85,83.7,76.34,70.56,70.2,70.4
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,62.4,60.91,58.98,67.15,79.45,85.24,86.93,84.96,77.1,72.0,70.9,71.85

我的代码是这样的:

awk '{ sum += $5 + $6 + $7 + $8 + $9 + $10 + $11 + $12 + $13 + $14
+ $15 } END { print sum / (NR * 18) }' observatory_1.txt > observatory_3.txt


output: 0.104394

我想创建一个txt文件夹,如下所示:

OBSERVATORY, Abbreviations, COUNTRY, ALTITUDE(m), LONGITUDE(deg), LATITUDE (deg), MEAN
Beverly-Begg Observatory Dunedin, , New Zealand,  140, 170, 490, -45,8644, 89,05583333

任何建议将不胜感激。

答案1

您的脚本对每个输入行中的一堆列进行求和,然后在读取所有输入行后,END 块将打印一个输出行...因此它在生成任何输出之前处理整个文件。

您应该做的是单独处理每个输入行。

您的列号似乎也有偏差 - 例如,为什么您要在平均值计算中包括海拔、经度和纬度?我假设您实际上想要第 7 至 19 列(1 月至 12 月)的平均值。

不管怎样,你可能想要更多这样的东西:

awk -F, -v OFS=, '
     NR == 1 { print $1, $2, $3, $4, $5, $6, "MEAN" }
     NR  > 1 {
       sum = 0;
       for (i=7; i<=19; i++) { sum += $i }
       print $1, $2, $3, $4, $5, $6, (sum / 12)
     }' observatory_1.txt > observatory_3.txt

这将产生如下输出:

OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.0558
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.1992
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.1558

这可能不完全是您想要的,但它应该是朝着正确方向迈出的一步。

答案2

使用(以前称为 Perl_6)

raku -e 'put get.split(",")[0..5].join(",") ~ ",MEAN"; \
      for lines() {my @a = .split(","); \
      put (@a[0...5].join(",") ~ "," ~ @a.[6..*].sum / @a.[6..*].elems)};'  

或者

raku -ne 'state $i=0; ++$i; my @a = .split(","); $i == 1 \
      ?? put @a.[0..5].join(",") ~ ",MEAN" \
      !! put (@a[0...5].join(",") ~ "," ~ @a.[6..*].sum / @a.[6..*].elems);'  

输入示例:

OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),January,February,March,April,May,June,July,August,September,October,November,December
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.93,86.84,85.26,88.22,89.36,89.8,88.52,90.42,88.74,89.06,91.16,91.36
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,63.92,60.44,58.63,65.68,75.97,85.7,84.85,83.7,76.34,70.56,70.2,70.4
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,62.4,60.91,58.98,67.15,79.45,85.24,86.93,84.96,77.1,72.0,70.9,71.85

示例输出(对于上面的两种代码解决方案):

OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.055833
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.199167
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.155833

简要解释第一个答案:get标题行、split逗号和put前 6 列,然后MEAN 使用.split(",")[0..5].join(",") ~ ",MEAN". (ICYMI,~波形符用于连接 Raku 中的字符串)。

现在,在第二行(第一个数据行)处使用逐行读取游标,for lines()读取输入(逐行),逗号split上的 s","并将元素存储在@a数组中。前六列@a[0..5]put用 计算的平均值@a.[6..*].sum / @a.[6..*].elems

请注意,您可能可以使用 硬编码列索引@a.[6..17].sum / @a.[6..17].elems,如果它始终是 12 列,您可以@a.[6..17].sum / 12这样做。最后, @a.[6..17].map(*.chars > 0).sum如果您需要调整缺失值,请用作分母。

https://raku.org

答案3

我们可以使用 GNU 来做到这一点直流电RPN 计算器。但在此之前我们需要这 3 个转换,这是使用珀尔

  • 将非数字字段括在 [] 中
  • 数字字段的负号更改为 _
  • 将逗号更改为空格。
perl -F, -lane 'my $i;
  print join " ",  map {
    $i++ < ($.>1?3:@F) ? qq([$_]) : s/^-/_/r;
  } @F;
' file |
dc -e "
#### macros definitions
[q]sq [44an]sz # OFS set to  comma
[+z7<a]sa # aum last 12 entries
[SMz0<b]sb # shunt remaining to M
[LMnz6>zzz6>c]sc # print LIFO M
[?z0=q
  lax #sum last 12 cols
  lbx #store all in stack M
  lcx #print
  LM12.0/p #orint average
cz0=?]s?

###> header processing
?[
  [4k]s0 [XrX=0z6<1]s1
  l1x lbx lcx [MEAN]pc
]x

##> non header lines
l?x
"

OBSERVATORY,Abbreviations,COUNTRY,ALTITUDE(m),LONGITUDE(deg),LATITUDE (deg),MEAN
Beverly-Begg Observatory Dunedin,,New Zealand,140,170.49,-45.8644,89.0558
Aorangi Iti Observatory Lake Tekapo,,New Zealand,718,170.473,-44.0082,72.1991
Mount John Observatory Lake Tekapo,,New Zealand,945,170.465,-43.9874,73.1558

相关内容