【问题标题】:How to apply some mathematical operation depending upon some particular values of particular column如何根据特定列的某些特定值应用一些数学运算
【发布时间】:2021-03-07 13:35:52
【问题描述】:

我想使用 awk 在文本文件 data.dat 中以某种顺序进行一些数学运算。 下面给出了一个示例文件,但是,原始文件有 m*n 数组,

-0.00309 300.0000 27.48357484
-0.00309 350.0000 27.48339634
-0.00309 400.0000 27.48309821
-0.00309 450.0000 27.48263481
-0.00309 500.0000 27.48196302
-0.00309 550.0000 27.48104749
-0.00309 600.0000 27.47986237
-0.00309 650.0000 27.47839084
-0.00309 700.0000 27.47662366
-0.00309 750.0000 27.47455745
-0.00309 800.0000 27.47219313
0.83311 50.0000 -15.61462258
0.83311 100.0000 -15.61504028
0.83311 150.0000 -15.61524246
0.83311 200.0000 -15.61547435
0.83311 250.0000 -15.61577002
0.83311 300.0000 -15.61597007
0.83311 350.0000 -15.61588681
0.83311 400.0000 -15.61538590
0.83311 450.0000 -15.61439714
0.83311 500.0000 -15.61289898
0.83311 550.0000 -15.61089993
0.83311 600.0000 -15.60842429
0.83311 650.0000 -15.60550308
0.83311 700.0000 -15.60216876
0.83311 750.0000 -15.59845261
0.83311 800.0000 -15.59438360

第一列从负数开始,在几行之后,它改变了它的符号(+ve)。 当第一列具有 -Ve 符号时,我想将第三列(在原始文件中会有所不同)乘以 1e-14,当第一列具有 +Ve 符号时,我想乘以 0.5e-14。

该文件非常大,所以我无法对其进行手动操作。 我可以使用

在整个文件中应用该操作
paste data.dat |  awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "0.5e-14" | awk '{print $2, $3, $4*$1}'

但这样做我可以一次使用一个操作(用于 -Ve 或用于 +Ve),这不是我的目标。

我想要一个循环,如果第一列是负数,它应该将第三列乘以数字 1e-14,如果第一列是 +Ve,它应该乘以 0.5e-14。

上述文件的预期结果是

-0.00309 300.0000 2.74836e-13
-0.00309 350.0000 2.74834e-13
-0.00309 400.0000 2.74831e-13
-0.00309 450.0000 2.74826e-13
-0.00309 500.0000 2.7482e-13
-0.00309 550.0000 2.7481e-13
-0.00309 600.0000 2.74799e-13
-0.00309 650.0000 2.74784e-13
-0.00309 700.0000 2.74766e-13
-0.00309 750.0000 2.74746e-13
-0.00309 800.0000 2.74722e-13
0.83311 50.0000 -7.80731e-14
0.83311 100.0000 -7.80752e-14
0.83311 150.0000 -7.80762e-14
0.83311 200.0000 -7.80774e-14
0.83311 250.0000 -7.80789e-14
0.83311 300.0000 -7.80799e-14
0.83311 350.0000 -7.80794e-14
0.83311 400.0000 -7.80769e-14
0.83311 450.0000 -7.8072e-14
0.83311 500.0000 -7.80645e-14
0.83311 550.0000 -7.80545e-14
0.83311 600.0000 -7.80421e-14
0.83311 650.0000 -7.80275e-14
0.83311 700.0000 -7.80108e-14
0.83311 750.0000 -7.79923e-14
0.83311 800.0000 -7.79719e-14

该操作将在 gnuplut 脚本中使用。

【问题讨论】:

    标签: bash awk gnuplot


    【解决方案1】:

    为什么要使用 awk?对于这样简单的事情,您可以使用 gnuplot 本身。 检查help ternary

    代码:

    ### conditional multiplication on columns
    reset session
    
    $Data <<EOD
    -0.00309 300.0000 27.48357484
    -0.00309 350.0000 27.48339634
    -0.00309 400.0000 27.48309821
    -0.00309 450.0000 27.48263481
    -0.00309 500.0000 27.48196302
    0.83311 300.0000 -15.61597007
    0.83311 350.0000 -15.61588681
    0.83311 400.0000 -15.61538590
    0.83311 450.0000 -15.61439714
    0.83311 500.0000 -15.61289898
    EOD
    
    myFactor(col1,col2) = column(col1) > 0 ? column(col2)*0.5e-14 : column(col2)*1e-14
    
    plot $Data u 1:(myFactor(1,3)) w lp pt 7
    ### end of code
    

    结果:(将要绘制的数据)

     -0.00309        2.74836e-13
     -0.00309        2.74834e-13
     -0.00309        2.74831e-13
     -0.00309        2.74826e-13
     -0.00309        2.7482e-13
     0.83311         -7.80731e-14
     0.83311         -7.80752e-14
     0.83311         -7.80762e-14
     0.83311         -7.80774e-14
     0.83311         -7.80789e-14
     
    

    加法:

    根据您的描述,我仍然不能 100% 确定我是否理解您想要的内容。这是一个尝试。实际上这是 gnuplot 的基础知识。

    代码:

    ### create 2 PNG output files
    reset session
    
    FILE = 'myData.dat'
    set term pngcairo size 600,300
    
    myFactor(col1,col2) = column(col1) > 0 ? column(col2)*0.5e-14 : column(col2)*1e-14
    
    set output 'Column1vs2.png'
    plot FILE u 1:(myFactor(1,2)) w lp pt 7 ti "Column3"
    
    set output 'Column1vs2and3.png'
    set ytics nomirror
    set y2tics nomirror
    plot FILE u 1:(myFactor(1,2)) axis x1y1 w lp pt 7 lc "red" ti "Column2", \
           '' u 1:(myFactor(1,3)) axis x1y2 w lp pt 7 lc "web-green" ti "Column3"
    
    set output
    ### end of code
    

    结果:

    【讨论】:

    • 它对我有用。您能否修改脚本以对第二列和第三列一起执行此操作。而不是只有第三列?
    • 你真正想要绘制什么?修改后的 column2 与修改后的 column3? plot $Data u (myFactor(1,2)):(myFactor(1,3)).
    • 我想绘制 column1 Vs colum2 和 3。在一种情况下,我只需要对 column3 进行操作,而在另一种情况下,我需要对第 2 列和第 3 列都进行操作。
    • 您是否希望 col2 和 col3 在一个绘图中具有相同的 x 轴 (col1),但 col2 具有左侧 y 轴,而 col3 具有右侧 y 轴,或者您想要两个单独的绘图在一个屏幕/画布?
    • 我希望它们出现在不同的情节中。在一个情节中,它将为:Col1 Vs col2 和 col3,在第二个情节中,我需要 Col1 Vs col2。
    【解决方案2】:

    awk 来救援!

    $ awk -v n='1e-14' -v p='0.5e-14' '{$3 *= ($1>0?p:n)}1' file
    
    -0.00309 300.0000 2.74836e-13
    -0.00309 350.0000 2.74834e-13
    -0.00309 400.0000 2.74831e-13
    -0.00309 450.0000 2.74826e-13
    -0.00309 500.0000 2.7482e-13
    -0.00309 550.0000 2.7481e-13
    -0.00309 600.0000 2.74799e-13
    -0.00309 650.0000 2.74784e-13
    -0.00309 700.0000 2.74766e-13
    -0.00309 750.0000 2.74746e-13
    -0.00309 800.0000 2.74722e-13
    0.83311 50.0000 -7.80731e-14
    0.83311 100.0000 -7.80752e-14
    0.83311 150.0000 -7.80762e-14
    0.83311 200.0000 -7.80774e-14
    0.83311 250.0000 -7.80789e-14
    0.83311 300.0000 -7.80799e-14
    0.83311 350.0000 -7.80794e-14
    0.83311 400.0000 -7.80769e-14
    0.83311 450.0000 -7.8072e-14
    0.83311 500.0000 -7.80645e-14
    0.83311 550.0000 -7.80545e-14
    0.83311 600.0000 -7.80421e-14
    0.83311 650.0000 -7.80275e-14
    0.83311 700.0000 -7.80108e-14
    0.83311 750.0000 -7.79923e-14
    0.83311 800.0000 -7.79719e-14
    

    【讨论】:

    • 这对我有用。您能解释一下“$1>0?p:n”这个术语是如何工作的吗?我认为“:”在这里像其他地方一样工作。对吗?
    • 另外,能否请您修改这个脚本,我想在第二列和第三列一起做这个操作。而不是只有第三列?
    • $1&gt;0?p:n 是三元运算符,与if($1&gt;0) p else n 相同。我认为在回答问题后修改问题是不礼貌的。目前,此脚本完全按照问题中的要求执行。但是,也很容易将相同的模式应用于第二个字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多