【问题标题】:How to read line that is 1000 or more lines above/under the current line?如何读取当前行上方/下方 1000 或更多行的行?
【发布时间】:2014-08-27 10:56:13
【问题描述】:

我需要一些帮助来阅读 bash 中的行。

我有 x, y, z(x,y) 格式的图形。(它是 3 列的文本文件) 这是大约。 1000x1000 点大,所以基本上是 1000000 列。

我想找到局部最大值,所以我需要检查当前点前后的点999,1000、1001,以及当前行前后的一行。我不想跟踪 2k 值(或者我应该?)

有什么想法吗?

编辑: 好像不太清楚。

有 3 列带有数字,如下所示:

0,0,0
0,1,0
0,2,0
1,0,0
1,1,1
1,2,0
2,0,0
2,1,0
2,2,0 

所以,第三列在某种程度上依赖于前两列,我想找到该列的局部最大值,在这种情况下,我想得到结果

1,1,1

在这里,我只有一个最大的点,但原则上,我正在寻找局部最大值,所以我想要所有这些。

编辑 2:

文件中的所有数字都是双精度的。

对于这个混乱,我感到非常抱歉,我是这个论坛的新手,而且我是 bash 编程的新手。

【问题讨论】:

  • 我认为你只问了你实际在做什么的一小部分,如果不知道其他一些事情,很难提出一个好的答案......你用什么方法来找到局部最大值你在和他们做什么?我的意思是,你是在用眼睛看周围的点吗?还是您将它们传递给另一个脚本?当你找到它们时你在做什么?您是否正在绘制它们,如果是,如何绘制?
  • 希望我现在说清楚了。感谢您的评论。
  • 感谢您在 Stack Overflow 上订购自定义代码。我们目前正在等待您预付 100 万美元(小额账单),以便我们开始为您解决问题。 --或者,您可以发布您拥有的代码和错误消息,并解释您认为代码可能存在的问题。
  • 您还没有解决的两个问题。 1) 局部最大值是大于其所有邻居的值,还是大于或等于所有 ita 邻居的值? 2)在你的网格边缘会发生什么 - 如果一个点在边缘并且它的上方/下方/左/右没有值,它仍然可以是最大值吗?
  • 差不多清楚了 -- 你如何定义'最大值'? 是向量| sqrt(x^2 + y^2 + z^2) |的大小,还是仅仅是依赖z的最大值(这就是它的外观)?

标签: bash max local


【解决方案1】:

编辑答案

好的,我已经阅读了您的新解释,但我仍然不确定我是否理解您,但我认为您有一个二维数组值,并且您正在寻找任何大于其直接邻居的点。对吗?

我会使用这样的东西:

awk -F',' 'BEGIN {xmin=ymin=1000;xmax=ymax=-1000}

           {x=$1; y=$2
            if(x<xmin)xmin=x
            if(y<ymin)ymin=y
            if(x>xmax)xmax=x
            if(y>ymax)ymax=y
            grid[$1 SUBSEP $2]=$3
           }

     END   {
             for(x=xmin+1;x<=xmax-1;x++){
               for(y=ymin+1;y<=ymax-1;y++){
                  this=grid[x SUBSEP y];
                  if((this>grid[x-1 SUBSEP y-1]) &&
                     (this>grid[x-1 SUBSEP y  ]) &&
                     (this>grid[x-1 SUBSEP y+1]) &&
                     (this>grid[x-1 SUBSEP y  ]) &&
                     (this>grid[x+1 SUBSEP y  ]) &&
                     (this>grid[x+1 SUBSEP y-1]) &&
                     (this>grid[x+1 SUBSEP y  ]) &&
                     (this>grid[x+1 SUBSEP y+1]))
                     print x,y,this;
               }
            }
           }' file

-F 表示您的字段用逗号分隔。在开始时(在BEGIN{} 块中)我将我看到的xy 的最小值和最大值初始化为一些不太可能的大/小值,当我稍后在下一步中读取您的数据时这些值将被覆盖.

然后,当我阅读每一行时,我提取xy 值并检查它们是否大于或小于我迄今为止看到的最大xy。这样我就会知道你的网格的限制——即最小 x 值、最大 x 值、最小 y 值和最大 y 值。我还将看到的每个值保存在数组 grid[] 中,该数组由您的 xy 值索引。

最后,在整个文件被读取之后,(在END{} 块中)我循环遍历所有我看到的x 和所有y 值。对于每个xy,我从grid[] 数组中获取z 值。然后我检查这个值是否大于它的所有 8 个邻居,如果是,我打印出来。

请注意,这不会处理网格边缘的最大值 - 为此,您必须将 for 循环更改为 for(x=xmin;x&lt;=xmax... - 以及 y 循环。

原始答案

我不确定我是否完全理解你的问题,所以如果我错了,请解释(而不是投反对票)我误解了什么,我会更正我的答案。

我想你想要这样的东西:

awk -v r=11000 'BEGIN{
                 w[r-1]++; w[r]++; w[r+1]++;
                 w[r-1001]++;w[r-1000]++;w[r-999]++;
                 w[r+999]++;w[r+1000]++;w[r+1001]++
               } 
               NR in w{print $0}' file

基本上你传入你感兴趣的行号,在这个例子中记录11000。然后,在开始时,awk 计算您想要查看的所有行号并将它们存储在数组 w[] 中 - 将其视为 wanted 的行。然后,在读取每条记录时,它会检查该记录是否是您想要的记录,如果是则打印它。

输出是这样的:

10,999,7
10,1000,7
11,1,7
11,999,7
11,1000,7
12,1,7
12,999,7
12,1000,7
13,1,7

如果您愿意,可以将其做成这样的单线:

awk -v r=11000 'BEGIN{w[r-1]++;w[r]++;w[r+1]++;w[r-1001]++;w[r-1000]++;w[r-999]++;w[r+999]++;w[r+1000]++;w[r+1001]++} NR in w{print $0}' file

请注意,awk 行号从1 开始,因此您可能需要相应地调整r 的值以获得您实际意思的确切行。

【讨论】:

  • 我认为你的解释是正确的,但遗憾的是,我不知道 awk 这么好(这就是我问的原因),我不知道它到底会做什么。我试图在“编辑”中澄清问题,如果不清楚喷射,我会更加努力.. =)
  • 我又试了一次,请再看一遍。
  • 这应该只适用于整数,对吗?如果所有数字都是实数(双精度),这不起作用?
  • @LukaPetrović 它应该适用于整数和双精度 - 它不在乎。
  • 如果不是 1000x1000 而是 1000000x1000000,那么代替 BEGIN {xmin=ymin=1000;xmax=ymax=-1000} 我写 BEGIN {xmin=ymin=1000000;xmax=ymax=- 1000000} ?
【解决方案2】:

让我们来看看这个文件:

0,0,0
0,1,0
0,2,0
1,0,0
1,1,1
1,2,0
2,0,0
2,1,0
2,2,0

如果您想在比赛中获得 2 分 (1,1,1),您可以通过以下方式实现:

$ cat mydata | grep -C2 -e '1,1,1'
0,2,0
1,0,0
1,1,1
1,2,0
2,0,0

当然,您可以在匹配点之前/之后更改要获取的行数:

-C<lines> # Above and After
-B<lines> # Before
-A<lines> # After

您也可以尝试为任何 x 匹配特定的 y 和 z 值:

cat t | grep -C2 -e '^[0-9]\+,\s*1,\s*3'

【讨论】:

  • 对不起,我的问题没有说清楚,你误会了。我的错。我编辑了它,希望它现在可以理解了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 2015-06-19
  • 2017-10-28
  • 2019-07-31
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多