比较两个包含浮点数据的csv文件并打印它们的差异统计数据

比较两个包含浮点数据的csv文件并打印它们的差异统计数据

我有两个 csv 文件:a.csv 和 b.csv。这两个文件都包含相同的行集。例如:

a.csv:

Yield
5.68
1.34
1.47
9.01
7.59

b.csv:

Yield
5.68
2.01
0.78
7.98
8.17

我需要比较这两个文件(文件始终具有相同的顺序,即 a.csv 中的第 i 行始终对应于 b.csv 中的第 i 行)并打印以下统计信息:

a.csv is greater than b.csv in 2/5 cases.
a.csv is smaller than b.csv in 2/5 cases.
a.csv is equal to b.csv in 1/5 cases.

参考:我已经编写了一个 R 代码来做到这一点,但想在 Unix 本身中完成这件事,也许使用 awk?

a <- read.csv('path/a.csv')
b <- read.csv('path/b.csv')
sum(a > b)
sum(a < b)
sum(a == b)

答案1

$ paste a.csv b.csv | awk -F '\t' 'NR > 1 { ++cmp[$1>$2 ? 1 : $1==$2 ? 0 : -1] } END { printf "greater\t= %d\nsmaller\t= %d\nequal\t= %d\n", cmp[1],cmp[-1],cmp[0] }'
greater = 2
smaller = 2
equal   = 1

awk这将使用为短程序创建一个两列输入paste。的内容a.csv将位于第一个字段中,而 的内容b.csv将位于第二个字段中,它们之间有一个制表符。

标题行被丢弃,第一个代码块递增数组中三个计数器之一cmpcmp[1]如果第一个字段 ( a.csv) 大于第二个字段 ( b.csv),则 的值会递增。cmp[0]如果两个字段相等,则的值会递增。cmp[-1]如果第二个字段大于第一个字段,则的值会递增。

最后,在END块中打印结果。

Perl 中也有同样的事情,使用它的 spaceship 操作符<=>

$ paste a.csv b.csv | perl -a -F'\t' -e '$. > 1 && ++$cmp{$F[0] <=> $F[1]}; END { printf "greater\t= %d\nsmaller\t= %d\nequal\t= %d\n", $cmp{1},$cmp{-1},$cmp{0} }'
greater = 2
smaller = 2
equal   = 1

$.NRin Perl 与inawk或多或少相同,因此$. > 1会跳过输入中的标题行。如果您使用过-MEnglish,则可以更改$.$NR

答案2

在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
FNR==1 { next }
NR==FNR {
    v[FNR] = $1
    next
}
{
    if      ( v[FNR] > $1 ) { gt++ }
    else if ( v[FNR] < $1 ) { lt++ }
    else                    { eq++ }
}
END {
    tot = gt + lt + eq
    printf "%s is greater than %s in %d/%d cases.\n", ARGV[1], ARGV[2], gt, tot
    printf "%s is smaller than %s in %d/%d cases.\n", ARGV[1], ARGV[2], lt, tot
    printf "%s is equal to %s in %d/%d cases.\n",     ARGV[1], ARGV[2], eq, tot
}

$ awk -f tst.awk a.csv b.csv
a.csv is greater than b.csv in 2/5 cases.
a.csv is smaller than b.csv in 2/5 cases.
a.csv is equal to b.csv in 1/5 cases.

相关内容