Listen aus .dat Datei erstellen

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
simsalabim
User
Beiträge: 6
Registriert: Montag 9. Dezember 2019, 13:34

Guten Tag zusammen,

ich weiß bei folgendem Problem nicht, wie ich weiter vorgehen soll. Ich habe eine .dat Datei, unten ist ein kleiner Ausschnitt daraus und ich möchte Listen erstellen, mit denen sich das ganze grafisch darstellen lässt. Also eine für die Zeit t und die jeweiligen Koordinaten. Bei meinem unteren Versuch ist das ganze zwar bereits als Array dargestellt, aber hieraus, kann ich mir nicht die erste Spalte für die Zeit ausgeben lassen. Der Grund hierfür ist vermutlich, dass das entstandene Array nur eindimensional ist. Ich habe anschließend mit 'shape' herumexperimentiert, aber bin auf keine Lösung gestoßen, die funktioniert... Habt ihr Ideen, was zu tun ist. Vielen Dank schonmal für evt. Hilfe!

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt

def is_float(string):
    try:
        return float(string)
    except ValueError:
        return False

data = []
with open('meineDatei.dat') as f:
    d = f.readlines()
    for i in d:
        k = i.rstrip().split(",")
        data.append([float(i) if is_float(i) else i for i in k]) 

data = np.array(data)
print(data)

Code: Alles auswählen

#iterations timestep  tmax
10001 0.001 10
#           Sun                Earth                 Jupiter             
#t     x      y      z      x     y       z      x      y     z 
0.000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000 5.2000 0.0000 0.0000 
0.001 0.0000 0.0000 0.0000 1.0000 0.0063 0.0000 5.2000 0.0023 0.0000 
0.002 0.0000 0.0000 0.0000 0.9999 0.0126 0.0000 5.2000 0.0046 0.0000 
0.003 0.0000 0.0000 0.0000 0.9998 0.0188 0.0000 5.2000 0.0068 0.0000 
0.004 0.0000 0.0000 0.0000 0.9997 0.0251 0.0000 5.2000 0.0091 0.0000  
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@simsalabim: Gewöhne Dir so Namen wie `f`, `d`, `i`, und `k` am besten gar nicht erst an. Namen sollen dem Leser verraten was der Wert für eine Bedeutung hat. `i` geht dabei noch wenn es eine ganze Zahl ist und als Index verwendet wird, aber ganz sicher nicht als Name für eine Zeichenkette, denn damit rechnet niemand.

Überleg mal was ``i.rstrip().split(",")`` macht und warum das bei den gezeigten Daten nicht sinnvoll ist.

`readlines()` ist hier überflüssig weil man über das Dateiobjekt iterieren kann, statt das vorher komplett in den Speicher zu lesen.

Für ein Numpy-Array müssen alle Elemente den gleiche Typ haben. Wenn Du da Zahlen und Zeichenketten vermischst, dann wählt Numpy für alles den allgemeinsten Typ aus, also in diesem Fall eine Numpy-Zeichenkette, das heisst Zeichenketten mit fester maximaler Länge innerhalb des Arrays mit denen man nicht rechnen kann:

Code: Alles auswählen

In [60]: np.array([0.0, "x"])                                                   
Out[60]: array(['0.0', 'x'], dtype='<U32')

In [61]: np.array([0.0, "x"])[0]                                                
Out[61]: '0.0'

In [62]: np.array([0.0, "x"])[0] + 42                                           
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-cbaefe430a6b> in <module>
----> 1 np.array([0.0, "x"])[0] + 42

TypeError: must be str, not int
Du möchtest Dir vielleicht mal `numpy.loadtxt()` anschauen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
simsalabim
User
Beiträge: 6
Registriert: Montag 9. Dezember 2019, 13:34

Vielen Dank für deine Antwort blackjack. Allein mit dieser Zeile bin ich ja schon näher dran, als zuvor.

Code: Alles auswählen

column = np.loadtxt('meineDatei.dat', usecols=[0], dtype=object)
Noch handelt es sich ja um Zeichenketten und außerdem muss ich die ersten Zeilen 'loswerden'. Da werde ich erstmal ein bisschen probieren und melde mich bei auftretenden Problemen noch einmal.
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@simsalabim: `dtype` auf `object` zu setzen ist falsch. Das ist so gut wie nie eine gute Idee. Numpy ist für Zahlen da und Du solltest `loadtext()` zahlen liefern lassen. Überlesen von Zeilen kann man damit auch machen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Verwende pandas. Die read_csv-Funktion sollte dir helfen ein pandas-DataFrame zu erzeugen. Dies kannst auch auch leicht mit matplotlib plotten lassen. Hier ein Schnipsel für dein Beispiel:

Code: Alles auswählen

import pandas as pd
import matplotlib.pyplot as plt

daten_sun = pd.read_csv(r'planeten-daten.txt', sep=' ', skiprows=4, index_col=0, usecols=[0, 1, 2, 3], names=['t', 'x', 'y', 'z'])
daten_earth = pd.read_csv(r'planeten-daten.txt', sep=' ', skiprows=4, index_col=0, usecols=[0, 4, 5, 6], names=['t', 'x', 'y', 'z'])
daten_jupiter = pd.read_csv(r'planeten-daten.txt', sep=' ', skiprows=4, index_col=0, usecols=[0, 7, 8, 9], names=['t', 'x', 'y', 'z'])
ax = daten_sun.plot(y='y', kind='line', label='Sun')
daten_earth.plot(y='y', kind='line', label='Earth', ax=ax)
daten_jupiter.plot(y='y', kind='line', label='Jupiter', ax=ax)
plt.show()
Antworten