在PowerShell中的数据集中查找统计模式

问题描述 投票:0回答:1

此问题是this question的后续问题:

如何确定给定数据集(数组)statistical mode,即最常出现的一个值或一组值?

例如,在数组1, 2, 2, 3, 4, 4, 5中有两种模式,24,因为它们是最频繁出现的值。

powershell statistics
1个回答
0
投票

[使用Group-ObjectSort-ObjectForEach-Object的组合:

# Sample dataset.
$dataset = 1, 2, 2, 3, 4, 4, 5

do { # dummy loop to allow efficient termination of the pipeline
  $dataset | Group-Object | Sort-Object Count -Descending | 
    ForEach-Object -Begin { $topCount = 0 } -Process { 
      if ($_.Count -lt $topCount) { break } # No longer top occurrence count, exit
      $topCount = $_.Count # Store the occurrence count.
      $_.Group[0] # Output the input value represented by the group.
    }
} while ($false)

以上产生24,这是两种模式(值最频繁出现,在这种情况下,每次出现两次);模式按输入顺序返回。

注意:虽然此解决方案在概念上很简单,但是可能需要考虑大型数据集的性能;有关某些输入可能的优化,请参见底部。

说明:

  • Group-Object按相等性对所有输入进行分组。

  • [Group-Object按成员计数以降序对结果组进行排序(首先出现最频繁的输入)。

  • Sort-Object -Descending命令循环遍历已排序的组,并为出现次数(频率)最高的/所有组输出每个代表的输入。

产生虚拟Sort-Object -Descending循环的原因是,从PowerShell Core 7.0.0-preview.5开始,如果不再需要处理其他输入,则没有direct方式退出管道。

有一个ForEach-Object添加对此的支持。

解决方法是使用一个封闭的loop并以ForEach-Object代替它。注意:not在没有封闭循环的管道中使用dolongstanding feature request on GitHub,因为它会在封闭循环中查找调用堆栈并退出脚本(如果没有)。

相反,虽然break 可以在管道的break块内使用,但它仅跳到next输入项-它不会停止处理其他输入。] >


更好的解决方案:

如果输入元素统一为简单数字或字符串

(相对于复杂对象),则可以进行优化:
  • [continuereturn禁止收集每个组中的各个输入。

  • 每个组的ForEach-Object属性反映了分组值,但是作为string

  • 起作用,因此必须将其转换回其原始数据类型。
Group-Object
© www.soinside.com 2019 - 2024. All rights reserved.