Seite 1 von 1

Daten von single-column format in multi-column Format konvertieren

Verfasst: Samstag 23. März 2019, 18:02
von HeyHo26
Hallo,

ich habe ein "Problem" und zwar werden meine Daten für mehrere Messstellen und Zeitschritte in einer Spalte raus geschrieben, heißt Zeitschritt 1, alle Messstellen und deren Werte. Der nächste Zeitschritt wird dann direkt darunter geschrieben mit der Information der vergangenen Zeit. Ich hätte es aber gerne als eine m * t+1 Matrix, also mit den m verschiedenen Messstellen als erste Spalte und für jeden Zeitschritt t dann eine extra Spalte. Klar kann ich das auch alles händisch mit Excel umformatieren, aber ich dachte mit python könnte ich mir da ne Menge Zeit sparen.

Eine Dummy Input Datei, sieht in etwa so aus und ist tab getrennt:
Zeit 1.5
Messstelle Messwert
1 23
2 45
3 23

123423 45
Zeit 1.75
Messstelle Messwert
1 33
2 21
3 55
….

usw.

Ziel wäre dann sowas:
Messstelle 1.5 1.75 …
1 23 33 …
2 45 21 …
3 23 55 …



Mein aktueller Workaround ist, die Eingangsdatei nach jedem Zeitschritt zu splitten, diese Splits in eine seperate Datei schreiben, und diese Dateien jeweils in ein dataframe einzulesen und sie zu mergen. Bei sehr großen Datenmengen - wo meist auch die Excel Zeilenbeschränkung deutlich überschritten wird - ist dies aber sehr langsam und ineffizient, daher die Frage, ob es nicht was schnelleres gibt :)

Code: Alles auswählen

#File umkonvertieren
s = open("Input.dat").read()
s = s.replace('Zeit, '#\nMessstelle')# Raute als split marker setzen
s = s.replace('Messstelle	Messwert\n', '')
f = open("Input_h.dat", 'w') 
f.write(s)
f.close()

#Splitten zu mehreren Text Dateien
with open ("Input_h.dat") as fo:
    op=''
    start=0
    cntr=1
    for x in fo.read().split("\n"):
        if (x=='#'):
            if(start==1):
                with open (str(cntr)+'.txt','w') as opf:
                    opf.write(op)
                    opf.close
                    op=''
                    cntr+=1
            else:
                start=1
        else:
            if(op==''):
                op=x
            else:
                op=op+'\n'+x

    fo.close()

#löschen der Hilfsdatei
os.remove('Input_h.dat')

#Einlesen der Textdateien ins Dataframe
i=1
while i<cntr:
    df="df_"+str(i)
    #print(df)
    df=pd.read_csv(str(i)+'.txt', sep='\t', )
    #print(df.head())
    if i==1:
        df_summary=df
    elif i>1:
        df_summary=df_summary.merge(df, on="Messstelle", how="left" )
    #löschen der Hilfsdateien
    import os
    os.remove(str(i)+'.txt')
    i=i+1


Grüße und vielen lieben Dank im voraus!

P.S. Ich bin kein Informatiker oder Informatikstudent, ich versuche mir mit python autodidaktisch meine Datenanalyse zu vereinfachen, also nicht zu böse sein, wenn ich was falsch labele oder einen komplett schwachsinnigen Algorithmus verwende :)

Re: Daten von single-column format in multi-column Format konvertieren

Verfasst: Samstag 23. März 2019, 21:35
von ThomasL
Habe mir mal diese Datei erzeugt
https://we.tl/t-o4YNEk6nCq
und dies hier auf die Schnelle gecodet

Code: Alles auswählen

import pandas as pd

df = pd.read_csv('messdaten.tsv', sep='\t', header=None, names=['Messstelle', 'Messwert'])
df.dropna(axis=0, how='any', inplace=True)

zeit = df.query('Messstelle=="Zeit"').Messwert.tolist()

df.drop(df[df['Messstelle'] == 'Zeit'].index, axis=0, inplace=True)
df.set_index('Messstelle', inplace=True)
print(df)

Code: Alles auswählen

            Messwert
Messstelle          
1               11.0
2               12.0
3               13.0
123423          14.0
1               21.0
2               22.0
3               23.0
123423          24.0
1               31.0
2               32.0
3               33.0
123423          34.0
1               41.0
2               42.0
3               43.0
123423          44.0

Code: Alles auswählen

# Habe auf die Schnelle keine Lösung um die Anzahl der Messtellen zu berechnen
# muss daher manuell vorgegeben werden
COUNT = 4

daten = pd.DataFrame(df.iloc[0:COUNT].Messwert.tolist(), columns=[zeit[0]], index=df.iloc[0:COUNT].Messwert.index)
for i in range(1, COUNT):
    daten[zeit[i]] = df.iloc[i*COUNT:(i+1)*COUNT].Messwert.tolist()

print(daten)

Code: Alles auswählen

            1.50  1.75  2.00  2.25
Messstelle                        
1           11.0  21.0  31.0  41.0
2           12.0  22.0  32.0  42.0
3           13.0  23.0  33.0  43.0
123423      14.0  24.0  34.0  44.0

Re: Daten von single-column format in multi-column Format konvertieren

Verfasst: Samstag 23. März 2019, 21:47
von Sirius3
Du liest die Datei ›Input.dat‹ komplett in den Speicher, ersetzt dann ein bißchen was und schreibst die Daten in ›Input_h.dat‹, nur um exakt die selben Daten wieder zu lesen. Das Schreiben und Lesen kannst Du Dir also sparen. Wenn man Dateien mit dem with-Statement öffnet, braucht man kein close (das man wenn man es benutzt auch aufrufen sollte). Warum fehlt das beim ersten ›open‹? Und warum benutzt Du bei den ersten zwei ›open‹ kein ›with‹?
›if‹ ist keine Funktion, die Klammern also allesamt überflüssig.
Generell, man liest Dateien Zeilenweise, dann spart man sich Speicher und es ist auch klarer, dass man eine Zeilenweise aufgebaute Datei hat.
Die letzte while-Schleife wäre auch eine for-Schleife, um das mehrfache zusammenbauen der Dateinamen zu verhindern, würde man eine Liste anlegen, über die man dann iterieren kann.
Insgesamt sieht das mehr nach C aus, als nach Python.

Wenn die Daten schlecht mit pandas zu lesen sind, dann mach das doch mit einfachem Python:

Code: Alles auswählen

from collections import defaultdict
data = defaultdict(list)
with open("Input.dat") as lines:
    for line in lines:
        key, value = line.split()
        data[key].append(value)
del data['Messstelle']