我有兩個大型 CSV 可供比較。兩個 csvs 基本上都是來自同一系統的資料,相隔 1 天。行數約為 12k,列數為 30。
目的是確定主鍵(#ID)的哪些列資料已更改。
我的想法是遍歷 CSV 以識別哪些行已更改并將它們轉儲到單獨的 csv 中。完成后,我再次遍歷更改行,并確定列中的確切更改。
NewCSV = Import-Csv -Path ".\Data_A.csv"
OldCSV = Import-Csv -Path ".\Data_B.csv"
foreach ($LineNew in $NewCSV)
{
ForEach ($LineOld in $OldCSV)
{
If($LineNew -eq $LineOld)
{
Write-Host $LineNew, " Match"
}else{
Write-Host $LineNew, " Not Match"
}
}
}
但是一旦運行回圈,就需要永遠運行 12k 行。我希望必須有一種更有效的方法來比較大檔案 powershell。更快的東西。
uj5u.com熱心網友回復:
好吧,您可以嘗試一下,我并不是說對于vonPryz已經指出的內容來說它會很快,但它應該為您提供一個很好的并排視角來比較從 OldCsv 到 NewCsv 的變化。
注意:在兩個 CSV 上具有相同值的單元格將被忽略。
$NewCSV = Import-Csv -Path ".\Data_A.csv"
$OldCSV = Import-Csv -Path ".\Data_B.csv" | Group-Object ID -AsHashTable -AsString
$properties = $newCsv[0].PSObject.Properties.Name
$result = foreach($line in $NewCSV)
{
if($ref = $OldCSV[$line.ID])
{
foreach($prop in $properties)
{
if($line.$prop -ne $ref.$prop)
{
[pscustomobject]@{
ID = $line.ID
Property = $prop
OldValue = $ref.$prop
NewValue = $line.$prop
}
}
}
continue
}
Write-Warning "ID $($line.ID) could not be found on Old Csv!!"
}
uj5u.com熱心網友回復:
正如vonPryz 在評論中所暗示的那樣,您已經撰寫了一個具有二次時間復雜度的演算法(O(n2)以 Big-O 表示法) - 每次輸入大小加倍時,執行的計算數量就會增加 4 倍。
為了避免這種情況,我建議使用哈希表或其他字典型別來保存每個資料集,并使用輸入中的主鍵作為字典鍵。通過這種方式,您可以獲得相應記錄的恒定時間查找,并且您的演算法的時間復雜度變得接近線性 ( O(2n k)):
$NewCSV = @{}
Import-Csv -Path ".\Data_A.csv" |ForEach-Object {
$NewCSV[$_.ID] = $_
}
$OldCSV = @{}
Import-Csv -Path ".\Data_B.csv" |ForEach-Object {
$OldCSV[$_.ID] = $_
}
現在我們可以通過它的 ID 有效地決議每一行,我們可以用一個獨立的回圈檢查整個資料集:
foreach($entry in $NewCSV.GetEnumerator()){
if(-not $OldCSV.ContainsKey($entry.Key)){
# $entry.Value is a new row, not seen in the old data set
}
$newRow = $entry.Value
$oldRow = $OldCSV[$entry.Key]
# do the individual comparison of the rows here
}
像上面那樣做另一個回圈,但用$NewCSV代替$OldCSV來查找/檢測洗掉。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384888.html
