numpy array

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
ch_neu
User
Beiträge: 9
Registriert: Freitag 20. Oktober 2017, 09:01

Hallo,

ich habe folgendes Problem.

In einem Script lese ich aus einem Textfile in einer Schleife Zeilen mit 2 Messwerten pro Zeile ein.

Code: Alles auswählen

 
 
import numpy as np

while True:
        
        try:
            zeile=zeilen[a]

            zeile=zeile[:-1]
            zeile=zeile.split('\t')
        
            messwerte_.append(zeile[0::2])
                
            a=a+1
        
        except IndexError:
            break
            
messwerte=np.array(messwerte_)
Mit dem letzten Befehl mache ich daraus einen schönen Spaltenvektor den ich mit [x,x] indizieren kann.



Dasselbe funktioniert aber in einem anderen Script leider überhaupt nicht. Rein prinzipiell lese ich auch dort die Daten aus einem Textfile ein und will daraus einen 2 Spaltenvektor erstellen. Was mit dem np.array() aber nicht gelingt.

In dem einen fall habe ich wenn ich den numpy vektor öffne den korrekten Spaltenvektor mit dtype=<12 und im zweiten Fall einen Zeilenvektor mit dtype=object. Wobei ich dann die Elemente klarerweise nicht mit [x,x] indizieren kann.

Leider bin ich noch kein Python Profi und habe keine Ahnung warum das so ist.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@ch_neu: leider werde ich aus Deiner Frage nicht schlau. Kannst Du Beispieldaten posten, und ein lauffähiges Programm dazu, bei dem der Fehler auftritt?

Wenn Du Messwerte hast, sind das doch Zahlen? Die lädt man am besten mit numpy.loadtxt oder ähnlichem.

Übrigens hast Du die komplizierteste Art einer for-Schleife geschrieben, die ich je gesehen habe:

Code: Alles auswählen

import numpy as np

messwerte = []
for zeile in zeilen:
    zeile = zeile.rstrip().split('\t')
    messwerte.append(zeile[::2])
messwerte = np.array(messwerte)
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da fehlen Dinge. Die zeilen fallen einfach vom Himmel. Außerdem hast du dir die größtmögliche Mühe gegeben überkompliziert zu iterieren. Ein simples

Code: Alles auswählen

for zeile in zeilen:
   .... 
erspart dir die while-Schleife, die Zählvariable und das try/except.

Woher dein eigentliches Problem kommt kann man nicht sagen, weil man ja nich sieht, wie Zeilen zustande kommt. Generell aber gilt: Daten aus Dateien sind Text/strings. Wenn du Zahlen willst, musst du konvertieren. ZB mit float(“10.3”). Oder du schaust dir gleich Pandas an, das macht ganz viel für dich automatisch.
ch_neu
User
Beiträge: 9
Registriert: Freitag 20. Oktober 2017, 09:01

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
import os
from tkinter import filedialog as tk_FileDialog

plt.close("all")


def getFileDialogTitle(msg,title):

    if msg and title:
        return "%s - %s" % (title, msg)
    if msg and not title:
        return str(msg)
    if title and not msg:
        return str(title)
    return None 

def diropenbox(msg=None, title=None, default=None):

    title = getFileDialogTitle(msg, title)
    localRoot = tk_FileDialog.Tk()
    localRoot.withdraw()
    if not default:
        default = None
    f = tk_FileDialog.askdirectory(
        parent=localRoot
        , title=title
        , initialdir=default
        , initialfile=None
    )
    localRoot.destroy()
    if not f:
        return None
    return os.path.normpath(f)


####################################################################
title = "Auswertung Shaker CHN" 
msg = "Pick the directory that you wish to open."
s = diropenbox(msg, title, default="./") 
#s="Z:\\Pers Ordn\\Neubauer\\_Acceleration Sensor\\_Konkurrenz\\Messungen B&K Sensor\\Piezoscan"

os.chdir(s) 

all_files = os.listdir('.') 
filename = []
for names in all_files: 
    if names.endswith(".dat"):
        filename.append(names)

filename.sort()

flimit=30000 #[Hz]

for i in range(len(filename)): 
    
    datafile = filename[i]
    
    print(datafile)

    data= open(datafile,'r')  
    zeilen=data.readlines()
    data.close()

    messwerte_=[]
    
    
    for zeile in zeilen[1:]:

            zeile=zeile.rstrip().split('\t')
      
            messwerte_.append(zeile[0::2])
                
    messwerte=np.array(messwerte_)
    
    fvec=messwerte[:,0]
    #fvec=fvec.tolist()
    
    for j in range(len(fvec)):
        
        hilf=int(fvec[j])
        if hilf>=flimit:
            break
        
 
    fig=plt.figure(i)
    plt.plot(messwerte[:j,0],messwerte[:j,1])
    plt.grid()
    plt.xlabel('Frequenz f [Hz]')
    plt.ylabel('Amplitude')
    plt.title(datafile[:-4])
    
    wm = plt.get_current_fig_manager()
    wm.window.state('zoomed')
    
    #plt.savefig(datafile[0:-4]+".png",dpi='figure')

    #plt.subplot_tool()
    
  

Code: Alles auswählen

f [kHz] 	 ratio 	 Phase [°] 
10 	 	 1.587000 	 	 121.100000 
20 	 	 219.900000 	 	 99.400000 
30 	 	 102.200000 	 	 92.800000 
40 	 	 54.580000 	 	 88.600000 
50 	 	 33.360000 	 	 88.300000 
60 	 	 25.020000 	 	 83.400000 
70 	 	 16.270000 	 	 82.700000 
80 	 	 14.510000 	 	 79.300000 
90 	 	 12.190000 	 	 80.800000 
100 	 	 11.410000 	 	 81.500000 
110 	 	 10.480000 	 	 79.000000

Danke für eure Hilfe soweit. Das hat mir schon mal was gebracht. Der Vollständigkeit halber mein ganzer Code und ein Teil der Datei die eingelesen werden muss. Habe ich mit numpy.loadtxt() nicht das Problem, dass ich Probleme habe wenn irgendwo was anderes als Zahlen stehen, bzw. hab ich noch nicht herausgefunden wie man nur mit numpy.loadtxt() nur bestimmte Zeilen einlesen kann?
Vielleicht noch die ergänzende Frage wie ich es schaffe, dass die geplottenen figures maximiert abgespeichert werden können?

Ich werde das andere Beispiel, wo ich Probleme mit dem Einlesen der Daten habe, noch aufbereiten.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@ch_neu: hast Du Dir die Hilfe von loadtxt schon mal durchgelesen? Das dürfte die meisten Deiner Fragen beantworten.

Zu Deinem Code
Zeile 6: bei einem frischen Programmlauf, was soll da geschlossen werden? Weg damit.
Zeile 9: getFileDialogTitle ist ein sehr spezieller Name für eine Funktion, die eigentlich was allgemeineres macht.
Zeile 28ff: Kommas schreibt man eigentlich am Ende einer Zeile
Zeile 44: niemals in einem Programm chdir benutzen. Das ändert einen globalen Zustand, so dass an anderer Stelle seltsame Effekte auftreten könnten. Nie machen.
Zeile 46: einfach glob.glob benutzen, dann spart man sich die for-Schleife

Code: Alles auswählen

filenames = sorted(glob.glob(os.path.join(s, '*.dat')))
Zeile 54: in der Datei stehen kHz, Du gibst hier Hz an, das kann nicht funktionieren.
Zeile 56: `for i in range(...)` ist ein Antipattern. In Python iteriert man direkt über Listen.
Zeile 62 bis 75: das ist ein numpy.loadtxt-Aufruf.

Code: Alles auswählen

messwerte = numpy.loadtxt(datafile, skiprows=1, usecols=[0,2])
Zeile 87: Du erzeugst eine Figure, die Du nicht benutzt.
Zeile 88: statt Messwerte abzuschneiden, einfach nur den x-Achsenbereich einschränken.

Code: Alles auswählen

filenames = sorted(glob.glob(os.path.join(s, '*.dat')))
for datafile in filenames:
    messwerte = numpy.loadtxt(datafile, skiprows=1, usecols=[0,2])
    plt.plot(messwerte[:, 0],messwerte[:, 1])
    plt.xlim(0, 30)
    plt.grid()
    plt.xlabel('Frequenz f [kHz]')
    plt.ylabel('Phase')
    plt.title(os.path.splitext(os.path.basename(datafile))[0])
ch_neu
User
Beiträge: 9
Registriert: Freitag 20. Oktober 2017, 09:01

Wow. Danke für die Antwort. Da hab ich jetzt viel gelernt. So richtig ist mir Python eben noch nicht vertraut, obwohl ich recht viel Matlab Erfahrung habe. Bzgl. der kHz - das ist einfach ein Fehler und sollte Hz sein - ist aber schon berücksichtigt.
Antworten