bash中的多个/分隔列

时间:2018-03-30 09:19:18

标签: bash shell unix dataframe awk

我的数据框看起来像这样:

ERR843978.19884 13 51 51
ERR843978.2880 10 49 51
ERR843978.10002 7 48 55
ERR843978.1158 8 45 54
ERR843978.4671 14 62 60
ERR843978.83 15 56 70
ERR843978.9406 8 56 39
ERR843978.8383 12 59 43
ERR843978.8916 6 51 42

我希望为所有行做到这一点:

column2/(column3*column4)

然后在新文件中打印输出。

我已经编写了一个bash脚本来执行它,但它有点慢,所以我正在寻找一个更有效的解决方案(可能使用awk?)。

这是我的代码

while read line
do
        out0=$(awk '{print $1}' <<< $line)
        out1=$(awk '{print $2}' <<< $line)
        out2=$(awk '{print $3}' <<< $line)
        out3=$(awk '{print $4}' <<< $line)
        out4=`echo "scale=5; ($out1 / ($out2 * $out3))"|bc -l`
        echo "$out0;$out4"
done < $file

2 个答案:

答案 0 :(得分:5)

是的, df = pd.DataFrame({'A':list('abcdef'), 'MRN':[4,5,4,5,5,np.nan], 'Number':[7,8,9,4,2,3], 'ResCat':[0,1,0,0,1,1], 'test':list('aaabbb')}) print (df) A MRN Number ResCat test 0 a 4.0 7 0 a 1 b 5.0 8 1 a 2 c 4.0 9 0 a 3 d 5.0 4 0 b 4 e 5.0 2 1 b 5 f NaN 3 1 b df1 = df.groupby("test") \ .agg({'MRN':'count', 'Number':'size', 'ResCat':lambda x: (x == 0).sum()}) \ .rename(columns={'MRN':'URT Use Count'}) \ .reset_index() print (df1) test URT Use Count Number ResCat 0 a 3 3 2 1 b 2 3 1 df1[['a','b']] = df1[['ResCat','URT Use Count']].div(df1['Number'], axis=0) print (df1) test URT Use Count Number ResCat a b 0 a 3 3 2 0.666667 1.000000 1 b 2 3 1 0.333333 0.666667 在这里非常有效:

awk

答案 1 :(得分:1)

如果您使用read拆分该行(如@Cyrus建议,但没有div

while read -r column1 column2 column3 column4
do
    echo "bc: $column1;$( echo "scale=5; ($column2 / ($column3 * $column4))"|bc )"
done < $file

它会快一点。在我的机器上6秒/ 1000行与1.7秒/ 1000行。

结合使用sedbcpaste

{
  echo "scale=5;"
  sed -re 's/(.*) ([0-9]+) ([0-9]+) ([0-9]+)/\2 \/ ( \3 * \4 )/' $file
} | bc > $$.tmp
cut -d ' ' -f 1 $file | paste - $$.tmp

它已在1.1秒/ 100000行中完成。这是~150的因素,并解释了为什么while循环声誉不佳。

使用ksh93,它允许浮点算法达到相似的数字。

typeset -F5 column2 column3 column4
while read -r column1 column2 column3 column4
do
    printf "printf %s;%.5f\n" "$column1 " "$(( column2 / (column3 * column4) ))"
done < $file

0.9秒/ 100,000行。这表明,它不是循环本身,而是在循环中使用外部命令bc

是的,awk仍然快~8倍,1.4秒/ 1,000,000行