Dateien mit Messdaten zu groß

Problemstellung

Je größer die Datei mit den Daten, desto länger braucht sie auch zum laden. Zerlegt man diese in mehrere, kleinere Fragmente, wächst mitunter die Datenmenge (die referenzierende Größe, meistens ein Timestamp, muss ja in jeder Datei vorhanden sein). Unterm Strich sind die einzelnen Dateien schneller geladen, da nicht immer die kompletten Messdaten geladen werden, sondern nur die, die gerade verarbeitet werden sollen. Doch wie zerlegt man „mal eben“ so eine Tabelle?

Problemlösung

In Excel? Wäre möglich, doch birgt das immer die Gefahr, dass man in Excel beim bearbeiten mit etwas Pech auch die Daten manipuliert (Thema Formatierung). Besser wäre da die Trennung der Daten so RAW wie möglich: Also direkt in txt-Form. Gehen wir mal davon aus, dass diese Daten im CSV-Format wie:

Time;Value1;Value2;Value3;Value4;Value5;...;ValueN
xxxx.xx.xx xx:xx:xx.xxx;0.000;0.000;0.000;0.000;0.000;...;0.000

vorliegen. Am Ende sollen mehrere Dateien entstehen, in denen immer die logischen Gruppen von Messwerten zusammen gefasst werden (zB. alle Spannungen, alle Ströme, alle Temperaturen, oder jeweils die Prüflinge mit allen Kenndaten).

Nehmen wir mal den einfacheren Fall: Die logischen Gruppen bestehen aus Messwerten, die hintereinander geschrieben sind, also nicht fragmentiert und die Gruppen reihen sich dann aneinander an. Lediglich der Timestamp ist fix. Zwar ließe sich das nun auch in Anlehnung der Visualisierung von Adresslisten in der Powershell erledigen, das Parsen als CSV ist hier jedoch nicht nötig und wäre nicht gerade performant. Bei einigen 100 tsd. bis 1 mio. Zeitpunkten x Werten macht das schon einen Unterschied. Daher hier mal als recht einfach Lösung (mit der Powershell). Etwas abgewandelt ist diese Lösung auch mit verschiedenen Timestamps nutzbar, zB. bei unterschiedlichen Messfrequenzen!

$infile   = "./indata.csv"
# Outputfilename
$outfile_a  = "./outputa.csv"
$outfile_b  = "./outputb.csv"
....
$outfile_x  = "./outputx.csv"
# num of columns to be processed
$n         = 99

# Daten lesen und gleich sortieren
Get-Content $infile | Foreach-Object {
  # split the line by ;
  $sline = $_.Split(';')
  # show the function is still running
  echo $($sline[0])
  
  # first group
  $line = $($sline[0])
  # loop over the first logical group, here column 2 to 5 eq values 1 to 4 
  for ($i = 1; $i -lt 5; $i++) {
    $line =  $($line) + ";" + $($sline[$i])
  }
  # at least replace all ',' by '.'. Will be better for tool like GNUPlot
  echo $line.replace(',','.') >> $outfile_a
  
  # secound group
  $line = $($sline[0])
  # loop over the secound logical group, here column 6 to 9 eq values 5 to 8 
  for ($i = 5; $i -lt 9; $i++) {
    $line =  $($line) + ";" + $($sline[$i])
  }
  # again replace all ',' by '.'. 
  echo $line.replace(',','.') >> $outfile_b
  
  ....
  
  # last group
  $line = $($sline[0])
  # loop over the last used logical group 
  for ($i = $n-5; $i -lt ($n+1); $i++) {
    $line =  $($line) + ";" + $($sline[$i])
  }
  # again replace all ',' by '.'. 
  echo $line.replace(',','.') >> $outfile_x
}
# say that all be fine and we are finished
echo "All work be done, up to the next"

An sich recht simpel: Zeile lesen, splitten, neu zusammen bauen, Punkt gegen Komma tauschen und wieder ausschreiben. Einziges Manko: Es kommen nachher immer utf16-kodierte Dateien heraus. Wer das nicht mag und keine Sonderzeichen drin hat, kann diese entweder vorab entsprechend anlegen, oder eben nachher umformatieren. Das lässt sich auch im Code direkt erledigen, war an der Stelle aber nicht nötig. Ergebnis sind dann eben mehrere Dateien, die jeweils den Timestamp und dann eine beliebige Anzahl von Messwerten beinhalten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert