Datei spaltenweise lesen

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.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Hallo,

ich habe eine Datei, die so aussieht:

Code: Alles auswählen

Zeit        x                 y                     z
12        200,9673      14,4022           11,9805
6         33,9673        18,4022           23,9805
24        72,9673       32,4022            44,9805
22        98,9673        55,4022           76,9805
ich möchte die Spaltenweise lesen und die Werte in Listen/Vektoren speichern, die erste Linie ist nicht relevant da sie char enthält und keine Float.

Die werte der Spalten brauche ich um eine numerische Funktionen zu berechnen.

Danke im Voraus
LG
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Schau dir mal das csv-Modul an, das genügt hier wahrscheinlich schon. Wenn du tatsächlich komplexe Berechnungen anstellen willst, bietet sich für das Einlesen unter Umständen auch numpy an.

P.S.: Es heißt übrigens Zeile und nicht Linie ;-)
Das Leben ist wie ein Tennisball.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Danke für die schnelle Antwort, ja Zeile( ich habe mich vertan).

So ich habe so viel rumprobiert bevor ich hier geschrieben habe, ich habe mit den beiden Bibliotheken versucht. Ich komme irgendwie nicht voran. kann man mir so ein Beipsiel Code zeigen. Vielleicht weiß ich voran ich immer gescheitert habe.
deets

Normalerweise laeuft das eher umgekehrt - du zeigst Code, und wir zeigen dir, wo es klemmt. Sonst kommt ein bisschen "mach meinen job"-feeling auf...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wie willst du dich in 13 Minuten denn mit zwei Modulen beschäftigt haben? In der Dokumentation zum csv-Modul sind doch genügend Beispiele, welche du erstmal testen kannst.
Das Leben ist wie ein Tennisball.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

So hier ein Versuch von mir

Code: Alles auswählen


data = [line.strip().split() for line in open("my_file.txt")]
t = []
data_y = []
    
for i in range(536):
    i = 1 # ignoriere erste Zeile
    data1 =  data[i][0] # erste Spalte
    data2 = data[i][3]
    t.append(data1)
    data_y.append(data2)

print t
print data_y
aber wenn ich ich auf data 1 oder data2 in eine Funktion benutze, kommt die Fehlermeldung:
TypeError: can't multiply sequence by non-int of type 'float'
Weiß jmd wie ich die Werte in Float casten kann?
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

EyDu, ich habe schon im Internet gelesen dass ich csv oder numpy benutzen kann. Und habe mich da eingelesen. Aufgrund meiner geringe Python Kenntnisse, kann ich nicht erreichen was ich erreichen möchte.

Hier eine Seite wo paar Beispiele stehen: http://www.scipy.org/Cookbook/InputOutput

Dennoch, bleibe ich immer wieder an eine Kleinigkeit stehen.

Wenn ich die Hilfe im Forum nicht gebraucht habe, hätte ich nicht geschrieben. Nicht jeder ist ein geborener Programmierer.
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Na, so schwer isses auch ned:

Code: Alles auswählen

import csv

with open('data.txt', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader)  #  header-Zeile ignorieren
    csvdata = list(reader)
    for row in csvdata:
        row[0] = int(row[0])
        for i, value in enumerate(row[1:], start=1):
            row[i] = float(value.replace(',', '.'))

import pprint
pprint.pprint(csvdata)
Übrigens bin ich auch kein geborener Programmierer, sondern hab mir das Programmieren halt einfach beigebracht.
Zuletzt geändert von pillmuncher am Montag 20. Februar 2012, 23:54, insgesamt 2-mal geändert.
In specifications, Murphy's Law supersedes Ohm's.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Danke,

aber dein Code wirft mir ein Fehler(ein Feher, der mich auch bei andren Codes gequählt hat und konnte nie wissen woran das liegt).

Code: Alles auswählen

row[0] = int(row[0])
IndexError: list index out of range
Zuletzt geändert von Marie am Montag 20. Februar 2012, 22:28, insgesamt 1-mal geändert.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

ich bin eigentlich mit der von mir gepoteten Version zufrieden, woltle nur wissen woran dieser Fehler liegt und wie ich das beheben kann?
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Marie hat geschrieben:ich bin eigentlich mit der von mir gepoteten Version zufrieden, woltle nur wissen woran dieser Fehler liegt und wie ich das beheben kann?
Dann benutzt du vielleicht Leerzeichen statt Tabs, dann musst du das „delimiter='\t'“ durch „delimiter=' '“ ersetzen.
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Vielleicht hast du auch Leerzeilen in deiner Datei. Dann so:

Code: Alles auswählen

import csv

with open('data.txt', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader)
    csvdata = [
        [int(row[0])] + [float(value.replace(',', '.')) for value in row[1:]]
            for row in reader if row
    ]

import pprint
pprint.pprint(csvdata)
In specifications, Murphy's Law supersedes Ohm's.
deets

Marie hat geschrieben:ich bin eigentlich mit der von mir gepoteten Version zufrieden, woltle nur wissen woran dieser Fehler liegt und wie ich das beheben kann?
Wirklich? Der funktioniert nicht, aus verschiedensten Gruenden. ZB deshalb, weil du i = 1 setzt, weil du hard-kodierte Zeilenanzahlen verwendest, und weil du strings einliest, aber irgendwann mit floats multiplizierst.

Setzt dich doch mal mit den angebotenen Beispielen auseinander. Und lass dir alle Zwischenschritte von deinem Code ausgeben mittels print. Achte auf Anfuehrungszeichen in der Ausgabe - dann hast du Strings, obwohl du floats willst.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Vielen Dank pillmuncher,

jetzt kann ich auf Spalten zugreifen

Code: Alles auswählen

import csv

data_mat = []
with open('my_file.txt', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader)
    csvdata = [
        [int(row[0])] + [float(value.replace(',', '.')) for value in row[1:]]
            for row in reader if row
    ]
   
    for i in range(len(csvdata)):
        data1 =  csvdata[i][0] #first row, first col
        data2 = csvdata[i][3]
Extrem Glücklich, vielen Dank an die anderen für eure Vorschläger ;)

LG
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Marie: Vielleicht sind die Felder nicht wie in csv üblich mittels eines einzelnen Zeichens (zB. ein Space oder ein Tab oder ein Komma) getrennt, sondern mit mehreren aufeinanderfolgenden Spaces. Dann hilft zB. dies:

Code: Alles auswählen

import csv

with open('data.txt', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=' ', skipinitialspace=True)  #  <-- Hier! Magie!!
    next(reader)  ##  header-Zeile ignorieren
    csvdata = [
        [int(row[0])] + [float(value.replace(',', '.')) for value in row[1:]]
            for row in reader if row
    ]

import pprint
pprint.pprint(csvdata)
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Marie hat geschrieben:Vielen Dank pillmuncher,
Gern geschehen.

Das hier allerdings ist nicht besonders:
Marie hat geschrieben:

Code: Alles auswählen

    for i in range(len(csvdata)):
        data1 =  csvdata[i][0] #first row, first col
        data2 = csvdata[i][3]
Lieber so:

Code: Alles auswählen

    for row in csvdata:
        data1 = row[0] #first row, first col
        data2 = row[3]
In specifications, Murphy's Law supersedes Ohm's.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Danke pillmuncher,

ich habe mich eigentlich verschrieben der kommen lautet
first column
. ich wiil auf die erste Spalte zugereifen.

nun habe ich leider ein neues Problem.

Code: Alles auswählen


from numpy import *
from scipy.optimize import leastsq
from math import *
import matplotlib.pyplot as plt
import numpy as np
import csv


data_mat = []
time_array = []
data_array =[]
with open('file.txt', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter='\t')
    next(reader) #header-Zeile ignorieren
    csvdata = [
        [int(row[0])] + [float(value.replace(',', '.')) for value in row[1:]]
            for row in reader if row
    ]
    
for i in range(len(csvdata)):
    data1 =  csvdata[i][0] #first col
    data2 = csvdata[i][3]
    time_array.append(float(data1))
    data_array.append(float(data2))

y = data_array
x = time_array
A1_0=4
A2_0=3
k1_0=0.5
k2_0=0.04
n1_0=2
n2_0=1
pname = (['A1','A2','k1','k2','n1','n2'])
p0 = array([A1_0 , A2_0, k1_0, k2_0,n1_0,n2_0])
""" Data plotten"""
def plot(x, y):
    line, = plt.plot(x,y, lw=2)
    plt.show()
    
def residuals(p, y, x):
    err = y-peval(x,p)
    return err
def peval(x, p):
    return p[0]*(1-np.exp(-(p[2]*x)**p[4])) + p[1]*(1- np.exp(-(p[3]*(x))**p[5] ))

plsq = leastsq(residuals, p0, args=(y, x), maxfev=2000)
ich bekomme dann ein Fehelrmeldung, die so lautet:

Code: Alles auswählen

err = y-peval(x,p)
ValueError: shape mismatch: objects cannot be broadcast to a single shape
irgendweilche Vorschläger wie ich das lösen könnte?
Danke im Voraus
LG
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Fehlermeldung sagt aus, dass ``y`` und das Ergebnis von ``peveal(x, p)`` verschiedene Dimensionen haben. Lass dir beide Werte mal ausgeben, dann siehst du das Problem.
Das Leben ist wie ein Tennisball.
Marie
User
Beiträge: 35
Registriert: Freitag 25. November 2011, 15:22

Danke EyDu für die Antwort,

ich glaube die Lösung ist einfach die beiden Array als numpy array auszugeben

Code: Alles auswählen

y = np.array(data_array)
x = np.array(time_array)
jetzt ist der Fehler verschwunden.
Danke für eure Tipps und Hilfe
LG
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

@Marie: Wenn du sowieso NumPy benutzt, bietet sich auch an dieses direkt zum Einlesen der Daten zu verwenden. Da du Kommas verwendest muss man leider noch einen Konverter definieren. Grundsätzlich würde ich es empfehlen immer einen Punkt zu verwenden.

Code: Alles auswählen

In [34]: import numpy as np

In [35]: def float2(s):
   ....:     return float(s.replace(',','.'))
   ....: 

In [36]: converters = {0: float2, 1: float2, 2: float2, 3: float2}

In [37]: data = np.loadtxt('test.dat', skiprows=1, converters=converters)

In [38]: data
Out[38]: 
array([[  12.    ,  200.9673,   14.4022,   11.9805],
       [   6.    ,   33.9673,   18.4022,   23.9805],
       [  24.    ,   72.9673,   32.4022,   44.9805],
       [  22.    ,   98.9673,   55.4022,   76.9805]])
Grüße
Gerrit

PS: Die *-Importe in deinem Code sind sehr gefährlich, weil Funktionen aus "numpy" von "math" Funktionen überschrieben werden. Die "math" Funktionen können allerdings nicht mit numpy arrays umgehen, wodurch du früher oder später "seltsame" Fehlermeldungen bekommst.

PPS: Sei dir bewusst das "y = data_array" keine Kopie von "data_array" an "y" gebunden wird!
Antworten