随机采样并输出最大值

随机采样并输出最大值

我有一个相当大的数据集~5亿行。数据集如下所示。第 1 列是浮点数,第 2 列是 mac id(设备 id)

1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2

该问题需要在对第 2 列进行分组后输出约 100,000 个随机样本,然后从该特定组的第 1 列中找到最大值。

中间输出如下所示(group by col1 ):

1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2497.93,d4:0b:1a:39:19:b2

之后,我需要每个分组的列中的最大值。输出如下所示:

3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2

最后一步是获得真正的随机样本,输出如下所示:

3540.68,18:f6:43:64:81:67
2872.32,c0:bd:d1:36:bb:49

任何想法,如何执行此操作。我刚刚开始使用 Linux,不知道如何执行如此艰巨的任务。任何帮助,将不胜感激。

答案1

尝试

BEGIN { srand() ;r=0 ; FS="," ; before="" ; }
{ if ( $1 > V[$2]) V[$2]=$1 ;
    if ( before != $2 && before != ""  ) {
          r=rand()*100 ;
       if ( r  > 50 ) printf "%s,%s\n",V[before],before ;
        }
 before=$2 ;
 }  data-file.txt

在哪里

  • if ( $1 > V[$2]) V[$2]=$1;获取 mac 的最大值
  • if ( before != $2 && before != "" ) {当新的 mac 值出现时
  • r=rand()*100 ; if ( r > 50 ) printf "%s,%s\n",V[before],before ;计算一个随机值,如果超过 50% 则打印(可以更改为 5% 或 95%)

答案2

5 亿行是大量数据,因此您可能希望寻找一种更具可扩展性的方式来处理这项工作。也就是说,使用标准 Linux 实用程序来完成此操作是可以实现的。

假设您的数据位于名为的文件中,data.txt 您可以使用以下命令将其打印到终端cat

$ cat data.txt
1616.93,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2497.93,d4:0b:1a:39:19:b2

sort然后可以使用选项将该输出通过管道传送到其中-t ',' -k 2。这些选项将指示sort使用逗号作为分隔符来分割数据,然后按第二列中的值进行排序:

$ cat data.txt | sort -t ',' -k 2
2854.11,18:f6:43:64:81:67
3540.68,18:f6:43:64:81:67
1616.93,ac:22:0b:a6:22:c3
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
2497.93,d4:0b:1a:39:19:b2
3314.55,d4:0b:1a:39:19:b2

对于您的下一个任务,您将需要使用sort选项-t ',' -k 1 -r。这将使用逗号作为分隔符和第一列中的值进行排序。将按-r尊敬的顺序排序,首先给出最大的条目:

$ cat data.txt | sort -t ',' -k 1 -r
3856.91,ac:22:0b:a6:22:c3
3540.68,18:f6:43:64:81:67
3314.55,d4:0b:1a:39:19:b2
2872.32,c0:bd:d1:36:bb:49
2854.11,18:f6:43:64:81:67
2497.93,d4:0b:1a:39:19:b2
1616.93,ac:22:0b:a6:22:c3

然后,您需要sort再次将上述示例的输出通过管道传输到其中,这次使用-t ',' -k 2 -u选项。和以前一样-t ','-k 2告诉 sort 使用第二列,而新选项-u告诉 sort 仅保留唯一的条目。

因为我们已按第一列中的值对数据进行排序,所以在查找唯一条目时,将首先找到最高的条目。这将为我们提供每个 MAC 地址的单个最高值:

$ cat data.txt | sort -t ',' -k 1 -r | sort -t ',' -k 2 -u
3540.68,18:f6:43:64:81:67
3856.91,ac:22:0b:a6:22:c3
2872.32,c0:bd:d1:36:bb:49
3314.55,d4:0b:1a:39:19:b2

最后,要获得随机样本,您可以使用shuf以下选项-n 2,其中 2 是您想要的随机样本数量:

$ shuf data.txt -n 2
3856.91,ac:22:0b:a6:22:c3
3314.55,d4:0b:1a:39:19:b2

答案3

供记录。这似乎有效,其他选项均无效

sort -t "," -k2,2 -k1,1 -r output.txt| awk -F "," '!a[$2]++'|head -100

相关内容