2013-08-06 83 views
1

我有兩個文本文件,每個文本文件的第一列包含時間戳覆蓋相同的時間但不是以相同的速率(第二個文件有更多的樣本)。但是,由於缺乏精確性,我收集的一些數據(位於這些文本文件的其他列中)在相同的時間戳內變化。文本文件處理沒有足夠精確的時間戳

例如,這是第二個文件

Timestamp RobotYaw 
1375448725 -2.183439 
1375448725 -2.173082 
1375448725 -2.169424 

和摘錄的第一個文件:

Timestamp State 
1375448725 8 
1375448725 9 

我想要做的就是創建一個輸出文件,該文件是一個副本第二個文件(它有更多的樣本),但有一個額外的列指定當前狀態(在第一個文件中給出)。然而,在上面的情況中,因爲時間戳不夠精確,我不知道何時發生狀態8到9的變化,並且我選擇了具有狀態8的時間戳的前半部分樣本,而另一半狀態9.

我正在努力做到這一點與Perl。現在,它將始終爲所有帶有該時間戳的樣本提供最新狀態(9)...

這是當前程序的一個框架,只保留最小值(這應該從第二個文件打印所有時間戳隨着當前狀態):

my $state = 1; 

while (my $ligne = <SECONDFILE>) 
{ 
    my ($timestamp , $junk) = split (/\s/ , $ligne) ; 

    while (my $checkline = <FIRSTFILE>) 
    { 
     my ($stateTimestamp , $stateJunk) = split (/\s/ , $checkline) ; 
     if (int($timestamp) < int($stateTimestamp)) 
     { 
      last; 
     } 
     else 
     { 
      $state = $stateJunk; 
     } 
    } 
    print OUTPUT $timestamp; 
    print OUTPUT " "; 
    print OUTPUT $state; 
    print OUTPUT "\n"; 
} 

請問您有什麼想法如何,我可以很容易地一個時間戳內處理這種狀態的任意變化?由於這是很難解釋,謝謝你的閱讀,如果你有任何問題,我會很樂意進一步解釋...

+0

我想你已經充分解釋了。給定多個樣本和多個狀態,您希望狀態在樣本中平均分佈。您需要指定如何處理邊緣情況(比樣本更多的狀態),以及如何在狀態數量不平均分割樣本數量時分配餘數。 –

+0

實際上,只有在文件一中的相同時間戳內存在狀態變化時,纔會出現此問題。在這種情況下,我的確選擇了在第二個文件中均勻分配狀態以獲取與時間戳對應的樣本。在其他情況下,我不需要這樣做,並且使用我的代碼獲得的狀態是正確的。 – wrousseau

回答

0

要知道什麼樣的打印哪個偏航時間戳,我們將需要閱讀在每個文件中加入一個散列。我們可以計算偏航時間戳的數量和樣本時間戳的數量,以便我們可以計算出要使用的樣本。這樣應該可以工作:

my %first_file; 
    my %second_file; 

    ### Store in a hash the unique timestamp|state values in order. 
    while (my $checkline = <FIRSTFILE>) { 
     my ($stateTimestamp, $statenum) = split /\s/, $checkline; 
     $first_file{$stateTimestamp}{'number'}++; 
     my $count = $first_file{$stateTimestamp}{'number'}; 
     $first_file{$stateTimestamp}{$count} = $statenum; 
    } 

    ### Store timestamp and yaw values 
    while (my $ligne = <SECONDFILE>) { 
     my ($timestamp , $robotyaw) = split /\s/, $ligne; 
     $second_file{$timestamp}{'number'}++; 
     $second_file{$timestamp}{$robotyaw} = $second_file{$timestamp}{'number'}; 
    } 

    ### MATH TIME IS FUN TIME. Don't forget to sort those hashes! 
    foreach (sort { $a <=> $b } keys %second_file) { 
     my $tstamp = $_; 
     my $valhash = $second_file{$tstamp}; 
     my $change_count = round_up($second_file{$tstamp}{'number'}/$first_file{$tstamp}{'number'}); 
     foreach (sort { ${$valhash}{$a} <=> ${$valhash}{$b} } keys %{$valhash}) { 
      my $yaw = $_; 
      if ($yaw eq 'number') { next; } 
      my $state_num = round_up(${$valhash}{$yaw}/$change_count); 
      print OUTPUT "$tstamp $yaw ", $first_file{$tstamp}{$state_num}, "\n"; 
     } 
    }  

    ### We could have used POSIX's ceil here instead 
    sub round_up { 
     my $n = shift; 
     return(($n == int($n)) ? $n : int($n + 1)); 
    } 

你也應該習慣使用3個參數開文件句柄::

open my $firstfile, '<', 'first_file.txt' or die "Can't open first file: $!"; 
open my $output, '>', 'output_file.txt' or die "Can't open output file: $!"; 

這樣,他們得到適當的作用域。

相關問題