如何获取由其他两个字段分组的CSV中的平均值?

时间:2014-10-29 22:43:56

标签: powershell csv command-line

我有一个类似

的CSV文件
TAG_ONE, 11, 10/27/2014,12:00:00 AM,11,Alm Disabled
TAG_ONE, 12, 10/27/2014,1:00:00 AM,11,Alm Disabled
TAG_ONE, 15, 10/27/2014,2:00:00 AM,11,Alm Disabled
TAG_ONE, 25, 10/27/2014,3:00:00 AM,11,Alm Disabled
TAG_ONE, 76, 10/28/2014,12:00:00 AM,11,Alm Disabled
TAG_TWO, 78, 10/27/2014,9:00:00 PM,11,Alm Disabled
TAG_TWO, 79, 10/27/2014,10:00:00 PM,11,Alm Disabled
TAG_TWO, 78, 10/27/2014,11:00:00 PM,11,Alm Disabled
TAG_TWO, 45, 10/28/2014,12:00:00 AM,11,Alm Disabled

我正在尝试获取一个新的CSV文件,该文件按日期(第三列)和标记(第一列)平均第二列中的所有值。 因此,对于每个标记,对于每个日期,我得到一行具有平均值。 有点像...

TAG_ONE, 15.75, 10/27/2014,12:00:00 AM,11,Alm Disabled
TAG_ONE, 76,    10/28/2014,12:00:00 AM,11,Alm Disabled
TAG_TWO, 78.33, 10/27/2014,12:00:00 AM,11,Alm Disabled
TAG_TWO, 45,    10/28/2014,12:00:00 AM,11,Alm Disabled

我对powershell完全不熟悉。我可以获得标记的所有值的平均值,但是也不能按日期将它们拆分,之后我就如何从中构建新的csv文件一无所知。

最终目标是为大量标签占用大量数据点,并将每个标签每天转换为一个数据点。

以下是我到目前为止的情况。我可以对项目进行分组并将其显示回来,但我似乎无法弄清楚如何在分组后对组中的所有值进行平均。我收到一个错误,即group.value无法找到,但如果我只是尝试打印$ item.group.value,那么它们都打印得很好。

$csv = import-csv -path \\psf\Home\Desktop\GitHub\iFix_Polling\Testing\HourlyTest.csv -header 'tag','value','date','time','unknown','alarm'

$collection = $csv | group-object -property tag,date

foreach( $item in $collection) {    
    $item | measure-object -property group.value -average
}

2 个答案:

答案 0 :(得分:2)

我会给我两位。我个人将事情分组,然后为每个组拍摄第一个项目,添加一个组成为该组平均值的成员,然后直接通过该项目。将其传递给select以获取所需的属性,并将其全部传递给Export-CSV:

$csv = import-csv -path \\psf\Home\Desktop\GitHub\iFix_Polling\Testing\HourlyTest.csv -header 'tag','value','date','time','unknown','alarm'
$collection = $csv | group-object -property tag,date
$collection | Foreach{
    $avg = $_.group|measure -Property Value -Average|select -expand average
    add-member -inputobject $_.group[0] -notepropertyname 'Average' -notepropertyvalue $avg -PassThru
}|Select Tag,Average,Date,SuperImportantNumber,AlarmStatus|Export-CSV $env:userprofile\desktop\Output.csv -notype

您已经拥有了一个非常好的对象,其中包含您想要的大部分数据,并没有太多理由让更多的对象成为您已有的虚拟副本。

这会将输出csv丢弃在桌面上。当然,您可以根据需要修改路径。

答案 1 :(得分:0)

如果您只对标签,数据和值感兴趣,那么这将很好地包含在一个简单的Select-Object中。

$data = Import-Csv e:\temp\data.txt -Header "Tag","Value","Date","Time","SuperImportantNumber","AlarmStatus"
$data | Group-Object -Property tag,date | Select-Object @{Label ="Tag"; Expression ={($_.Name.split(","))[0]}},
        @{Label ="Average"; Expression ={ [math]::Round(($_.Group.Value | Measure-Object -Average).Average,2)}},
        @{Label ="Date"; Expression ={($_.Name.split(","))[1]}}

否则你可以做这样的事情。不幸的是,它增加了比所需更多的复杂性,但它仍然有效。

$data = Import-Csv e:\temp\data.txt -Header "Tag","Value","Date","Time","SuperImportantNumber","AlarmStatus"
$data | Group-Object -Property tag,date | ForEach-Object{
    $singleObject = $_.Group | Select -First 1
    [pscustomobject][ordered]@{
        Tag = $singleObject.Tag
        Average = [math]::Round(($_.Group.Value | Measure-Object -Average).Average,2)
        Date = $singleObject.Date
        Time = $singleObject.Time
        SuperImportantNumber = $singleObject.SuperImportantNumber
        AlarmStatus = $singleObject.AlarmStatus
    }
} | Export-Csv -Path c:\temp\results.csv -NoTypeInformation

Group-Object是此代码的主要功能。使用它可以收集组中的对象。在我们的示例中,我们使用tagdate对信息进行分组。首先,我们将数据导入为csv。您的样本没有标题,所以我为您提供了标题。如果您有自己的-Header,则可以将其删除,但请记住,其余代码取决于标题名称。对于创建的每个组,我们创建一个包含导入文件的所有字段的自定义对象。我们使用$singleObject = $_.Group | Select -First 1来获取标记,日期和平均值之外的值。就个人而言,我没有看到在日期之后包含其他信息的理由,但是你在输出中有这个。平均值是从组中的所有Values计算得出的。 Measure-Object为我们进行平均,[math]方法Round为我们提供了2位小数。最后将它全部导出到csv。