我已經構建了幾個腳本來組織來自測試設備的數據輸出,但是我打了一個這個問題的心理障礙。使用散列構建排序數據表
測試設備監測來自多個主體(標識符爲ID1,ID2等)的四種輸入(Data1,Data2,Data3,Data4),並且每個間隔都記錄日期和時間戳。設備傾銷的CSV文件是這樣組織的:
Start,Date,Time0
Subject,ID1,ID2,[...],ID#
Date,Time1
Data1,aa1,aa2,[...],aa#
Data2,ba1,ba2,[...],ba#
Data3,ca1,ca2,[...],ca#
Data4,da1,da2,[...],da#
Date,Time2
Data1,ab1,ab2,[...],ab#
Data2,bb1,bb2,[...],bb#
Data3,cb1,cb2,[...],cb#
Data4,db1,db2,[...],db#
...等等。
「開始」將此行標識爲數據的開始; 「主題」將該行標識爲包含主題ID的行; 「Data1」 - 「Data4」將行標識爲包含該日期和時間指定的特定時間間隔內該數據類型的數據的行。
輸出數據因此被分成多個塊,這對於設備製造商來說確實是一個不幸的選擇,特別是在幾天或幾周內每隔幾分鐘收集一次數據時尤其如此。爲了分析數據,而無需手動選擇每6行,我們需要將所有的數據類型成塊,這樣的:
Data1,Subject,ID1,ID2,[...],ID#
Date,Time1,aa1,aa2,[...],aa#
Date,Time2,ab1,ab2,[...],ab#
...
Data2,Subject,ID1,ID2,[...],ID#
Date,Time1,ba1,ba2,[...],ba#
Date,Time2,bb1,bb2,[...],bb#
...
我們的目標是讓每個單獨的塊中的四種數據類型,從而使任何給定主題(ID1到ID#)的時間進程數據將在一個列中,日期和時間作爲初始列。 (上面的「DataX」和「Subject」僅用作列標題。)
目前我正在通過將每行放入一個單獨的數組中。這是完成任務的一種快速而骯髒的方式;該腳本獲取時間和日期,並將ID行插入四個數組中的每一個(每個數據類型一個),然後繼續根據數據類型順序添加每條數據行。輸出只是逐行打印每個數組,添加一個空行,然後打印下一個數組。這是有效的,但理想情況下,我想按主題ID對數據列進行排序,然後打印出數據,而不會丟失按日期和時間戳排序的垂直排序。 (因爲數據已經垂直排序,所以在打印之前,我目前沒有對陣列進行排序功能。)
要做到這一點,最簡單的方法是什麼?精神上,我試圖解析如何將Y行X列中的數據與CSV文件中列X中的主題ID相關聯時遇到問題。我使用的每個其他數據輸出文件都將主題ID保留爲每行中的第一項或者每個主題具有一個文件,這使得它更容易。
注意:因爲時間/日期是在他們自己的行上,所以我爲每個使用了一個變量;如果腳本檢測到包含新時間和/或日期的行,則會更新變量值。
編輯 - 我加入了一些鮑羅廷的建議(離開FH處理,而不是段落)。我已經從主題行數據被拉入的陣列(@ids),以及使用日期/時間和ID作爲鍵正在推動的數據行轉換爲哈希:
my ($datatype, @fields) = @line;
push @keys, $datatype unless exists $data{$datatype};
my $datetime = "$date\,$time";
push @timestamps, $datetime unless exists $data{$datetime};
for my $i (0 .. $#fields) {
push @{$data{$datetime}{$ids[$i]}}=>$fields[$i]
};
我也落下的日期時間對成第二個數組維護順序(@timestamps)。 現在的問題是我遇到問題時將值打印出來。目前嘗試:
foreach my $date (keys %data) {
print OUT $date;
foreach my $id (@ids) {
foreach my $s (keys %{$data{$date}}) {
if (exists($data{$date}{$id})) {
print OUT ",", $data{$date}{$id}
}
else {
print OUT ",";
}
}
}
print OUT "\n"; # close printing on a given date
}
繼續獲取垃圾輸出(打印散列引用,而不是實際值!)。自卸車輸出看起來是這樣的:
$VAR1 = {
'date,time' => [
'ID1' => [
'0.00'
]
'ID2' => [
'0.12',
]
'ID3' => [
'0.17',
]
'ID4' => [
'0.22',
]
]
}
};
和打印輸出是這樣的:
date,time,ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60)
對不起到目前爲止的例子已造成解釋的問題。輸入文件中有很多額外的數據和文本,我只包含了一個高度簡化的部分,我試圖提取和排序。
你的描述很不清楚。整個文件是否只有一個「Subject」?你爲什麼要複製四次?哪些字段可以用作鍵?例如每次都是相同的字符串「Data1」? 'Date'是實際日期還是字符串'Date'?如果可能的話,這將有助於看到一些真實的數據。 – Borodin 2013-04-24 17:12:18
「主題」是數據文件中行中的第一項。我當前的腳本使用它來識別這是包含ID列表的行。示例中的「日期」和「時間」是實際日期和時間戳的佔位符。四種數據類型中的每一種的字符串在每個數據塊中都是相同的,就像上面使用佔位符「數據1」到「數據4」所示的那樣。上面的主題ID由「ID1」,「ID2」等表示 - 將爲了清晰起見而編輯。 – 2013-04-24 17:45:16