[英]Filtering within a Group - Group-Object
背景信息:
每个元素的指标类型为“ 10”或“ ND”
指标的值为“!” ,''(空字符串/空),'o','u'
题:
我需要根据此伪代码规则过滤每个“元素”组中的数据,然后将结果导出到文件中:
对于每个“元素”组,如果指标='!' 或``对于BOTH IndicatorTypes(即'10','ND')两者,选择indicatorType = ND的组
如果指标='! 或对于IndicatorType = 10则为'',对于IndicatorType = ND则为Indicator ='o'或'u'
我的源文件:
"Code","IndicatorType","Indicator","Element","Data"
"111","10","","S","0.039"
"111","10","!","Cr ","0.045"
"111","10","","Zn","0.011"
"111","10","!","P","0.013"
"111","10","","Ni ","56.480"
"111","10","!","Co ","1.081"
"111","10","!","Fe","45.655"
"111","10","!","Si","0.364"
"111","10","!","Mn","0.005"
"111","10","!","Al","0.007"
"111","10","!","Cu","0.014"
"111","10","!","Y","0.00"
"111","ND","","S","0.037"
"111","ND","","Cr ","0.039"
"111","ND","","Zn","0.010"
"111","ND","","P","0.013"
"111","ND","o","Ni ","37.107"
"111","ND","o","Co ","0.887"
"111","ND","o","Fe","37.430"
"111","ND","","Si","0.348"
"111","ND","","Mn","0.005"
"111","ND","","Al","0.008"
"111","ND","","Cu","0.013"
"111","ND","","Y","0.00"
我的代码按Element分组:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName | Group-Object Element |
Where-Object -FilterScript {($_.Group.IndicatorType -eq 'ND' -and
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '') -or
($_.Group.IndicatorType -eq '10' -and
$_.Group.Indicator -eq 'o' -or
$_.Group.Indicator -eq 'u' -or
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '')
}| Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
问题:
问题出在我的Where-Object上,它返回所有值。
如何将伪代码规则应用于我的Where-Object以仅选择所需的组?
$_.Group
将返回同一元素的两个对象,因此您的测试将使用-eq
右侧的值过滤列表(例如组中两个对象的IndicatorType),并且条件很可能为true 。 例如:
$_.Group.IndicatorType -eq 'ND'
#Translates to array of "IndicatorTypes in the group" -eq 'ND'
10,'ND' -eq 'ND'
#The line above filters the array on the left to show matching values, this returns
'ND'
#A value is always true, so this test will be
$true
您可以通过在要首先执行测试的组中找到对象来解决此问题。
另外,使用Group-Object Element | Where-Object …
Group-Object Element | Where-Object …
表示如果where子句为true,则将保留从Group-Object
返回的整个对象(包含Count,Name和elements-group)。 您应该改用Foreach-Object
因为您只想为每个批准的元素组保留一个对象。 尝试:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName |
#For Each "Element" Group
Group-Object Element | Foreach-Object {
$Ten = $_.Group | Where-Object { $_.IndicatorType -eq '10' }
$ND = $_.Group | Where-Object { $_.IndicatorType -eq 'ND' }
if(('!','' -contains $Ten.Indicator) -and ('!','' -contains $ND.Indicator)) {
#if Indicator='!' or '' for BOTH IndicatorTypes(ie '10','ND'), Select group where indicatorType=ND
$ND
} elseif (('!','' -contains $Ten.Indicator) -and ('o','u' -contains $ND.Indicator)) {
#ELSE if Indicator='!' or '' for IndicatorType = 10 and Indicator='o' or 'u' for IndicatorType=ND Select group where indicatorType=10
$Ten
}
} | Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
Group-Object
返回GroupInfo
对象的集合, GroupInfo
对象都包含组中元素的集合-本质上是列表列表。 运行cmdlet会(基于示例输入)产生12个组的列表:
PS[1] (191) > $data = import-csv data2.txt | group-object element
PS[1] (192) > $data.Count
12
查看返回的第一项:
PS[1] > $data[0].Group.Count
2
您可以看到它包含两个看起来像的条目:
PS[1] (193) > $data[0].Group
Code : 111
IndicatorType : 10
Indicator :
Element : S
Data : 0.039
Code : 111
IndicatorType : ND
Indicator :
Element : S
Data : 0.037
这意味着您的选择标准将必须应用于与该组关联的数据集合中的每个/所有条目,以决定是否要返回该组。 在您的示例代码中,您似乎假设一个组不是一个平面。不幸的是,我不完全了解您要执行的操作,因此无法提供完整的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.