我的数据框看起来像这样:
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
答案 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行。
结合使用sed
,bc
和paste
{
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行