Semikolon statt Leerzeichen als Trennungszeichen in einer Datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Hallo,

Ich bin Anfänger in Python und verstehe noch viele Funktionen nicht
Ich will mehrere Datein einlesen lassen, bei denen das Trennungszeichen das Semikolon ist.

Dateien-Aufbau:

301462.5;-96.138351440429688;
301575;-95.929977416992188;
301687.5;-94.837844848632813;
301800;-95.316276550292969;
301912.5;-97.244903564453125;
302025;-96.163230895996094;
302137.5;-97.752456665039063;
302250;-95.189094543457031;
302362.5;-96.783187866210937;
302475;-96.819259643554688;
302587.5;-96.150192260742188;

Sonst habe ich immer folgendes benutzt, dabei war das Trennungszeichen das Leerzeichen:

Code: Alles auswählen

%matplotlib inline
import math
import numpy as np
import matplotlib as mpl
import random
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def readData(filename,skiprows=0):
    print('Read data from',filename)
    f = open(filename)
    data = np.loadtxt(f,skiprows=skiprows)
    return data

data = readData('./20170926_001.txt',skiprows=100) 
xaxis = data[:,0]  
yaxis = data[:,1]

xStart=300000
xStop=1000000
StartIndex=np.argmin((xaxis-xStart)**2)
StopIndex=np.argmin((xaxis-xStop)**2) # das braucht man, wenn man später in einem bestimmten Bereich fitten möchte

f = plt.figure()
plt.plot(xaxis,yaxis,'g-') # plotte gesamte Verteilung in grün
plt.plot(xaxis[StartIndex:StopIndex],yaxis[StartIndex:StopIndex],'b-') # plotte zu fittenden Bereich in blau
plt.title('Title')
plt.xlabel('x-Achse')
plt.ylabel('y-Achse')
plt.xlim([300000,1200000])
plt.grid()
plt.show()
Das Problem ist in Zeile

Code: Alles auswählen

 data = np.loadtxt(f,skiprows=skiprows)
Was muss ich dort hinzufügen, damit Python die Datei richtig einließt?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du Dir die Hilfe zu "loadtxt" schon angeschaut?
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Ja, habe ich. Das was ich herausgefunden, das die Funktion delimiter gibt, aber die hilft mir nicht. Wenn ich Funktion hinzufüge

Code: Alles auswählen

def readData(filename,skiprows=0):
    print('Read data from',filename)
    f = open(filename)
    data = np.loadtxt(f,skiprows=skiprows,delimiter=";")
    return data
erhalte ich die Fehlermeldung:

could not convert string to float: b'Freq Offset'

statt

could not convert string to float: b'Freq'

Was ist der unterschied?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nun versucht er eine Zeile mit Headern zu floats zu machen. Die hast du bei deinem Ausschnitt oben unterschlagen.

Dazu kannst du den Parameter skiprows verwenden. Den hast du ja schon eingebaut (bzw. wohl eher einkopiert :lol: )
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Mein Fehler. Ich hatte den Parameter skiprow einen zu kleinen Wert (5 statt 50) gegeben.

Ich erhalte nur die Fehlermeldung:

could not convert string to float:

statt die Fehlermeldung:

could not convert string to float: b'302475;-96.819259643554688;'
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da hast du schon wieder was verbockt, und den delimiter nicht genutzt. Fuer mich geht das hier:

Code: Alles auswählen

import io
import numpy as np

DATA = """301462.5;-96.138351440429688
301575;-95.929977416992188
301687.5;-94.837844848632813
301800;-95.316276550292969
301912.5;-97.244903564453125
302025;-96.163230895996094
302137.5;-97.752456665039063
302250;-95.189094543457031
302362.5;-96.783187866210937
302475;-96.819259643554688
302587.5;-96.150192260742188"""


def readData(inf, skiprows=0):
    data = np.loadtxt(inf, skiprows=skiprows, delimiter=";")
    return data

def main():
    print(readData(io.StringIO(DATA)))

if __name__ == '__main__':
    main()
Allerdings musste ich zuerst noch die trailing Commas entfernen! Und skiprows=50 klingt komisch... normalerweise musst du nur eine Zeile ueberspringen. Die mit den Headernamen drin. Nicht 50....
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Das was ich gezeigt habe war ein Auszug einer Datei mit 1.000.000 Einträgen und in den ersten 50 Zeilen stehen Einstellungsgrößen, die erstmal nicht wichtig sind.

Wie kann ich Python sagen, dass er die trailing Commas entfernt?
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Ok. Ich habe eine neue Datei erstellt, die folgenden Aufbau hat:
  • Preamplifier;NOT AVAILABLE;
    Transducer;OFF;
    Values;8001;
    300000;-95.252685546875
    300112.5;-98.109329223632813
    300225;-95.874794006347656
    300337.5;-95.150131225585938
    300450;-95.335540771484375
    300562.5;-97.074394226074219
    300675;-95.303787231445313
    300787.5;-96.119026184082031
    300900;-97.286239624023437
    301012.5;-96.832168579101563
    301125;-97.209907531738281
Dann funktioniert der Code auch.
Aber warum funktioniert das nicht wenn jede Zeile mit einem Semikolon beendet wird?
Was muss ich dann noch zusätzlich machen?

Code: Alles auswählen

%matplotlib inline
import math
import numpy as np
import matplotlib as mpl
import random
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def readData(filename,skiprows=0):
    print('Read data from',filename)
    f = open(filename)
    data = np.loadtxt(f,skiprows=skiprows,delimiter=";")
    return data

data = readData('./probe.txt',skiprows=30) 
xaxis = data[:,0]  
yaxis = data[:,1]

xStart=300000
xStop=1000000
StartIndex=np.argmin((xaxis-xStart)**2)
StopIndex=np.argmin((xaxis-xStop)**2) # das braucht man, wenn man später in einem bestimmten Bereich fitten möchte

f = plt.figure()
plt.plot(xaxis,yaxis,'g-') # plotte gesamte Verteilung in grün
plt.plot(xaxis[StartIndex:StopIndex],yaxis[StartIndex:StopIndex],'b-') # plotte zu fittenden Bereich in blau
plt.title('Zn Fluoreszenz-Spektrum')
plt.xlabel('ADC units [arb.]')
plt.ylabel('Counts')
plt.xlim([300000,301000])
plt.grid()
plt.show()
DelphiMarkus
User
Beiträge: 23
Registriert: Samstag 19. April 2008, 13:27
Wohnort: Münsterland

numpy trennt die Eingangsdaten in drei Spalten. Die ersten beiden enthalten deine Daten und die dritte entsteht dadurch, dass ein Semikolon immer als Trenner zwischen zwei Spalten gesehen wird. Der Fehler kommt daher, dass ein leerer String nicht in eine Fließkommazahl umgewandelt werden kann.

In der Dokumentation ist ein Parameter "usecols" erwähnt. Wenn du numpy Version 1.11.0 oder höher hast, kannst du den verwenden um nur die ersten beiden Spalten einzulesen.
Ansonsten musst du dir "genfromtxt" anschauen. Diese Funktion ist mächtiger als "loadtxt" und kennt den Parameter "usecols" auch in älteren Versionen von numpy.
conhar
User
Beiträge: 6
Registriert: Freitag 6. Oktober 2017, 22:10

Danke für eure Antworten.

Es funktioniert jetzt alles.
Antworten