将符号转换为相对概率

时间:2011-02-04 04:24:49

标签: bash math csv text-processing

背景

根据单词和标签的CSV文件创建概率词典。这是文本分段问题的前奏,而不是作业问题。

问题

给出一个包含以下单词和标签的CSV文件:

aardvark,10
aardwolf,9
armadillo,9
platypus,5
zebra,1

创建一个文件,其概率相对于文件中最大的标记:

aardvark,1
aardwolf,0.9
armadillo,0.9
platypus,0.5
zebra,0.1

例如,aardvark,1计算为aardvark,10/10platypus,0.5计算为platypus,5/10

问题

实现shell脚本以创建相对概率文件的最有效方法是什么?

约束

  • 字数和数字都没有任何顺序。
  • 没有主要的编程语言(例如Perl,Ruby,Python,Java,C,Fortran或Cobol)。
  • 欢迎使用标准Unix工具,例如awksedsort
  • 所有概率必须相对于文件中的最高概率。
  • 单词是唯一的,数字不是。
  • 这些标签是自然数字。

谢谢!

3 个答案:

答案 0 :(得分:3)

awk 'BEGIN{max=0;OFS=FS=","}  $NF>max{max=$NF}NR>FNR {print $1,($2/max) }' file file

答案 1 :(得分:2)

无需两次阅读文件:

awk 'BEGIN {OFS = FS = ","} {a[$1] = $2} $2 > max {max=$2} END {for (w in a) print w, a[w]/max}' inputfile

如果您需要按字词排序的输出:

awk ... | sort

awk 'BEGIN {OFS = FS = ","} {a[$1] = $2; ind[j++] = $1} $2 > max {max=$2} END {n = asort(ind); for (i=1; i<=n; i++) print ind[i], a[ind[i]]/max}' inputfile

如果您需要按概率排序的输出:

awk ... | sort -t, -k2,2n -k1,1

答案 2 :(得分:1)

这不是防错的,但是这样的事情应该有效:

#!/bin/bash

INPUT=data.cvs
OUTPUT=tally.cvs
DIGITS=1

OLDIFS=$IFS
IFS=,

maxval=0  # Assuming all $val are positive

while read name val
do
    if (( val > maxval )); then maxval=$val; fi
done < $INPUT

# Make sure $OUTPUT doesn't exist

touch $OUTPUT

while read name val
do
    tally=`echo "scale=$DIGITS; result=$val/$maxval; if (0 <= result && result < 1) { print "0" }; print result" | bc`
    echo "$name,$tally" >> $OUTPUT
done < $INPUT

IFS=$OLDIFS

借用this question和各种谷歌搜索。