基本問題是我有很多具有標準化名稱的資料點,這些資料點剛剛從服務器轉儲到檔案中,但是我需要根據它們包含的資料(在它們的標準化名稱)。
包含所有資料點的原始檔案如下(這些不是原始資料點標簽,而是簡化的標簽):
temp_r301
airflow_r301
temp_r345
airflow_r345
solar_w
solar_e
...
如您所見,它們都作為一列出現,因此每行有一個標簽。
我想組織它們,以便對于每個狀態(“溫度”,如溫度),我在同一行中有相應的資訊,例如:
temp_r301 301 airflow_r301 solar_w solar_e #airflow in 301 and general solar radiation affect temperature (state) in room 301
temp_r345 345 airflow_r345 solar_w solar_e #airflow in 345 and general solar radiation affect temperature (state) in room 345
當然,陣列的長度可能會有所不同,因此我們的想法是制作一種演算法來檢測長度并相應地組織資料。另外,我知道我將不得不使用正則運算式來查找匹配項并定義哪些資料點是狀態,哪些是輸入,以及知道它們所屬的房間。
到目前為止,我已經嘗試了以下方法:
use strict;
use warnings;
use diagnostics;
my @transpose = ();
my @sorted = ();
push(@sorted, [qw(temp_r301 temp_r345)]);
push(@sorted, [qw(301 345)]);
push(@sorted, [qw(airflow_r301 airflow_r345 solar_w solar_e)]);
for my $sorted (@sorted) {
for my $column (0 .. $#sorted) {
push(@{$transpose[$column]}, $sorted->[$column]);
}
}
for my $new_row (@transpose) {
for my $new_col (@{$new_row}) {
print "$new_col ";
}
print "\n";
}
但這只有在所有陣列都具有相同長度的情況下才能正常作業(不是這種情況)。
我還發現了一個回圈,可用于將資料存盤為矩陣形式(陣列陣列),但是,我似乎仍然無法找到將來自不同陣列的資料寫入矩陣的解決方案:
use strict;
use warnings;
use diagnostics;
use feature 'say';
my @states = qw(temp_r301 temp_r345);
my @zones = qw(301 345);
my @inputs = qw(airflow_r301 airflow_r345 solar_w solar_e);
my @matrix = ();
for my $x (0 .. $#states) {
for my $y (0 .. $#inputs) {
$matrix[$x][$y] = $states[$x]; #of course this only copies the states array and
} #repeats it for each created array
}
for my $aref (@matrix) { #print array of arrays
say "[ @$aref ],";
}
那么,知道我已將所有資料轉儲到輸入檔案中,將這些資料排序到矩陣中的最佳方法是什么?有沒有我應該更加注意的回圈?我應該使用陣列嗎?
uj5u.com熱心網友回復:
這個問題的細節仍然不清楚,但解釋確實有幫助。所以這就是我的假設。
我獲取資料以使每行有一條資訊。有些包含一個標簽(描述),后跟房間號,我假設 format tag_rN,標識標簽適用的房間號。
至于沒有房間號的其他人,則需要進行額外的處理來確定該資訊所屬的位置。這個問題只提出了一個適用于所有房間的標簽示例,與影響它們的太陽輻射有關(見評論),所以這就是所有處理的內容。
一些資料沒有按照房間整齊分類的事實使得決議資料的組織變得不重要。由于沒有給出詳細資訊,我只是將它分成兩個散列,一個按房間號,另一個根據具體結構而定。
use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd);
my $file = shift // die "Usage: $0 file\n";
open my $fh, '<', $file or die "Can't open $file: $!";
my (%room, %other);
while (<$fh>) {
chomp;
if ( my ($tag, $room_num) = /([^_] )_r([0-9] )/ ) {
$room{$room_num}{$tag} = $_; # have room number
}
else { # more processing needed
my ($tag, $value) = parse_line($_);
push @{ $other{$tag} }, $value;
}
}
dd \%room; dd \%other; say '';
# Print in CSV format. Header first
my @tags = ( keys %{ $room{ (keys %room)[0] } }, keys %other );
say join ',', 'room', @tags;
foreach my $rnum (keys %room) {
say join ',',
$rnum, map { $room{$rnum}{$_} // join ' ', @{$other{$_}} } @tags;
}
sub parse_line {
my ($line) = @_;
my ($tag, $value);
if ($line =~ /solar_w|solar_e/) { # example from sample data
$tag = 'solar';
$value = $line;
}
else { } # other possibilities
return $tag, $value;
}
帶有房間號的資料通過標識描述(“標簽”)作為鍵進行排序,行是它的值。每個這樣的鍵值對都在分配給每個房間號的 hashref 中。
沒有房間號的資料在一個單獨的子中決議,只有一些令牌代碼,因為沒有給出細節。然后將其存盤在另一個哈希中,以便于操作(因為它不系結到任何一個房間)。
如何從資料中提取標簽有點隨意,因為問題中沒有指定。
所有這些都組合成 CSV 格式。以上,帶有來自問題的輸入檔案和評論中的解釋,即來自西方和東方的太陽輻射影響所有房間,列印:
{
301 => { airflow => "airflow_r301", temp => "temp_r301" },
345 => { airflow => "airflow_r345", temp => "temp_r345" },
}
{ solar => ["solar_w", "solar_e"] }
room,airflow,temp,solar
345,airflow_r345,temp_r345,solar_w solar_e
301,airflow_r301,temp_r301,solar_w solar_e
用dd ...(from Data::Dump)注釋掉該行以洗掉初始診斷列印。然后最后幾行是將進入某個檔案等的 CSV。
某些房間可能缺少某些資料,還有更多資料可能無法如此統一分類。然后,這些標題的欄位將根據需要在某些行中為空。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/405159.html
標籤:
上一篇:運行時Perl/Tk中的未知問題
