【问题标题】:Using shell or bash to position block average large csv files使用 shell 或 bash 定位块平均大 csv 文件
【发布时间】:2015-03-31 20:19:21
【问题描述】:

假设我有一些看起来像这样的数据

1,2,2
3,4,5
4,5,6
1,2,3
4,5,6
1,2,2

包含在 csv 文件中。现在我想这样定位块平均值:添加块(例如两行)然后取平均值:

1,2,2
3,4,5
+
4,5,6
1,2,3
+
4,5,6
1,2,2

这会给

9,12,14
5,8,10

按块数 (3) 平均:

3,4,4.67
1.67,2.67,3.33

有没有一种简单的方法可以在 awk、sed、grep 或纯 bash 中实现这一目标?我的真实数据以 GB 为单位,因此它确实需要非常高效。

【问题讨论】:

  • 我现在在玩 awk:awk '{ sum += $1 } END { print sum }' file。而且我试图弄清楚如何在一个块中执行它,以便它对所有列求和,但也可以在块中执行它。 IE。在我上面的示例中,我想按位置和块数进行平均。我可以在 python 中快速执行此操作,但我的文件太大,无法成为有效的路径。

标签: bash shell csv awk sed


【解决方案1】:

以下是如何开始:

$ cat tst.awk    
BEGIN{ FS=OFS="," }
{
    for (i=1;i<=NF;i++) {
        sum[((NR-1)%2)+1,i] += $i
    }
}
END {
    for (j=1;j<=2;j++) {
        for (i=1;i<=NF;i++) {
            printf "%s%s", sum[j,i], (i<NF?OFS:ORS)
        }
    }
}

$ awk -f tst.awk file
9,12,14
5,8,10

稍后我会检查您是否有关于如何完成的问题。

【讨论】:

  • BEGIN{ FS=OFS="," } { for (i=1;i&lt;=NF;i++) { sum[((NR+1)%2)+1,i] += $i } } END { for (j=1;j&lt;=2;j++) { for (i=1;i&lt;=NF;i++) { printf "%s%s", sum[j,i]/(NR/2), (i&lt;NF?OFS:ORS) } } } 我在其中添加了位置划分(NR/Nr Rows in Block)。
  • (NR-1)%2+1 可能更容易使用,特别是对于较大的 2 值。
  • @rici 是的,使用 + 而不是 - 是一个错字,感谢您发现它。
猜你喜欢
  • 1970-01-01
  • 2013-04-09
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
相关资源
最近更新 更多