如何计算 shell 脚本中的标准差?

How do I calculate the standard deviation in my shell script?

我有一个 shell 脚本:

dir= 
cd $dir 
grep -P -o '(?<=<rating>).*' * | 
awk -F: '{A[]+=;L[]++;next}END
{for(i in A){print i, A[i]/L[i]}}' | sort -nr -k2 | 
awk '{ sub(/.dat/, " "); print }'

它总结了我文件夹中每个文件中 <rating> 字段后面的所有数字,但现在我需要计算数字的标准偏差而不是获取平均值。通过将文件中每个评分与均方的差异相加,然后将其除以样本大小 -1。我不需要在文件夹中的每个文件中执行此操作,而是在 2 个特定文件中执行此操作,hotel_188937.dathotel_203921.dat。以下是这些文件之一的内容示例:

<Overall Rating>
<Avg. Price>5
<URL>

<Author>Jeter5
<Content>I hope we're not disappointed! We enjoyed New Orleans...
<Date>Dec 19, 2008
<No. Reader>-1
<No. Helpful>-1
<rating>4
<Value>-1
<Rooms>3
<Location>5
<Cleanliness>3
<Check in / front desk>5
<Service>5
<Business service>5

<Author>...
repeat fields again...

第一个文件的样本大小为 127,平均值为 4.78,而第二个文件的样本大小为 324,平均值为 4.78。无论如何我可以改变我的脚本来计算这两个特定文件的标准偏差而不是计算目录中每个文件的平均值?感谢您的宝贵时间。

是的。

grep 行中的 * 告诉它在所有文件中搜索。

换行

grep -P -o '(?<=<rating>).*' * | 

grep -P -o '(?<=<rating>).*' hotel_188937.dat hotel_203921.dat | 

您可以在一个 awk 脚本中完成所有工作

$ awk -F'>' '
    =="<rating" {k=FILENAME;sub(/.dat/,"",k);
                   s[k]+=;ss[k]+=^2;c[k]++}
               END{for(i in s) 
                   print i,m=s[i]/c[i],sqrt(ss[i]/c[i]-m^2)}' r1.dat r2.dat

r1 2.5 1.11803
r2 3 1.41421

s 为求和,ss 为平方和,c 为计数,m 为均值。请注意,这计算的是总体标准差,而不是样本标准差。对于后者,您需要使用 (count-1) 进行一些缩放调整。