2015-11-25 3 views
0

Я новичок в Powershell. Я попытался обработать/перенести столбцы строк на запись csv среднего размера (около 10000 строк). Оригинальный CSV состоит из около 10000 строк с 3 колонками ("Time","Id","IOT"), как показано ниже:Powershell csv row column транспонирование и манипуляция

"Time","Id","IOT" 
"00:03:56","23","26" 
"00:03:56","24","0" 
"00:03:56","25","0" 
"00:03:56","26","1" 
"00:03:56","27","0" 
"00:03:56","28","0" 
"00:03:56","29","0" 
"00:03:56","30","1953" 
"00:03:56","31","22" 
"00:03:56","32","39" 
"00:03:56","33","8" 
"00:03:56","34","5" 
"00:03:56","35","269" 
"00:03:56","36","5" 
"00:03:56","37","0" 
"00:03:56","38","0" 
"00:03:56","39","0" 
"00:03:56","40","1251" 
"00:03:56","41","103" 
"00:03:56","42","0" 
"00:03:56","43","0" 
"00:03:56","44","0" 
"00:03:56","45","0" 
"00:03:56","46","38" 
"00:03:56","47","14" 
"00:03:56","48","0" 
"00:03:56","49","0" 
"00:03:56","2013","0" 
"00:03:56","2378","0" 
"00:03:56","2380","32" 
"00:03:56","2758","0" 
"00:03:56","3127","0" 
"00:03:56","3128","0" 
"00:09:16","23","22" 
"00:09:16","24","0" 
"00:09:16","25","0" 
"00:09:16","26","2" 
"00:09:16","27","0" 
"00:09:16","28","0" 
"00:09:16","29","21" 
"00:09:16","30","48" 
"00:09:16","31","0" 
"00:09:16","32","4" 
"00:09:16","33","4" 
"00:09:16","34","7" 
"00:09:16","35","382" 
"00:09:16","36","12" 
"00:09:16","37","0" 
"00:09:16","38","0" 
"00:09:16","39","0" 
"00:09:16","40","1882" 
"00:09:16","41","42" 
"00:09:16","42","0" 
"00:09:16","43","3" 
"00:09:16","44","0" 
"00:09:16","45","0" 
"00:09:16","46","24" 
"00:09:16","47","22" 
"00:09:16","48","0" 
"00:09:16","49","0" 
"00:09:16","2013","0" 
"00:09:16","2378","0" 
"00:09:16","2380","19" 
"00:09:16","2758","0" 
"00:09:16","3127","0" 
"00:09:16","3128","0" 
... 
... 
... 

Я пытался сделать транспонирование с помощью кода на основе из Powershell скрипт, загружаемый из https://gallery.technet.microsoft.com/scriptcenter/Powershell-Script-to-7c8368be
В основном мой PowerShell код, как показано ниже:

$b = @() 
    foreach ($Time in $a.Time | Select -Unique) { 
     $Props = [ordered]@{ Time = $time } 
     foreach ($Id in $a.Id | Select -Unique){ 
      $IOT = ($a.where({ $_.Id -eq $Id -and $_.time -eq $time })).IOT 
      $Props += @{ $Id = $IOT } 
     } 
     $b += New-Object -TypeName PSObject -Property $Props 
    } 
$b | FT -AutoSize 
$b | Out-GridView 

Выше кода может дать мне результат, как я ожидал, все значения "Id" станут заголовками столбцов, тогда как все значения "Time" станут уникальной строкой и значениями "IOT" как пересечение п от "Id" х "Time", как показано ниже:

"Time","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","2013","2378","2380","2758","3127","3128" 
"00:03:56","26","0","0","1","0","0","0","1953","22","39","8","5","269","5","0","0","0","1251","103","0","0","0","0","38","14","0","0","0","0","32","0","0","0" 
"00:09:16","22","0","0","2","0","0","21","48","0","4","4","7","382","12","0","0","0","1882","42","0","3","0","0","24","22","0","0","0","0","19","0","0","0" 

В то время как она включает в себя только несколько сотен строк, результат выходит быстро, как и ожидалось, но сейчас проблема при обработке весь файл CSV с 10000 строк, сценарий выше ' продолжать выполнять "и, похоже, не может закончить в течение длительного времени (часы) и не мог выплеснуть никаких результатов. Так что, возможно, если бы некоторые эксперты PowerShell из stackoverflow могли помочь оценить код выше и, вероятно, могли бы помочь изменить его, чтобы ускорить результаты?

Большое спасибо за советовании

+0

Я буду считать, что '$ a' из' Import-CSV'? – Matt

+0

И ... каждый раз будет делиться всеми одинаковыми идентификаторами? – Matt

+0

Это правда Mat, $ a - массив из import-csv. Из исходного файла csv каждое «время» будет повторять/делить все те же «Id». – peace888

ответ

0

10000 записей много, но я не думаю, что это достаточно, чтобы советовать streamreader * и вручную разбора CSV. Самое большое, что идет против вас, хотя это следующая строка:

$b += New-Object -TypeName PSObject -Property $Props 

Что PowerShell делает здесь делает новый массив и добавляя этот элемент к нему. Это очень интенсивная операция, которую вы повторяете 1000 раз. Лучше всего в этом случае использовать трубопровод в ваших интересах.

$data = Import-Csv -Path "D:\temp\data.csv" 
$headers = $data.ID | Sort-Object {[int]$_} -Unique 

$data | Group-Object Time | ForEach-Object{ 
    $props = [ordered]@{Time = $_.Name} 
    foreach($header in $headers){ 
     $props."$header" = ($_.Group | Where-Object{$_.ID -eq $header}).IOT 
    } 
    [pscustomobject]$props 
} | export-csv d:\temp\testing.csv -NoTypeInformation 

$data будет весь файл в память в качестве объекта. Необходимо получить все $headers, которые будут заголовками столбцов.

Группируйте данные по каждому из Time. Затем внутри каждого объекта времени мы получаем значение для каждого идентификатора. Если идентификатор не существует в течение этого времени, запись будет отображаться как null.

Это не лучший способ, но должен быть быстрее вашего. Я запустил 10000 записей за минуту (51 секунда в среднем за 3 прохода). Будет ли тест, чтобы показать вам, если смогу.

Я только что запустил ваш код с моими собственными данными, и это заняло 13 минут. Я думаю, что можно с уверенностью сказать, что моя работает быстрее.


пустышки данных был сделан с этой логикой FYI

1..100 | %{ 
$time = get-date -Format "hh:mm:ss" 
sleep -Seconds 1 
    1..100 | % { 

     [pscustomobject][ordered]@{ 
      time = $time 
      id = $_ 
      iot = Get-Random -Minimum 0 -Maximum 7 
     } 
    } 
} | Export-Csv d:\temp\data.csv -notypeinformation 

* Не звездный пример для случая StreamReader. Просто указывая на это, чтобы показать, что это лучший способ читать большие файлы. Просто нужно разбирать строки по строкам.

+0

Большое спасибо Мэтту, код выше действительно ускоряется намного быстрее. На самом деле, файл csv, который я упомянул, является только одним из ежедневных типов один, мне может понадобиться обработать то же самое с сотнями тысяч строк для ежемесячных файлов csv (размером около 20 мб за csv-файл), вы думаете, что 'streamreader' дело будет требоваться? Если это необходимо, если вы не возражаете, не могли бы вы бросить несколько примеров, используя технику streamreader? – peace888