Mehrzeilige und mehrspaltige Tabelle

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.
BlackJack

@anika_20: Das ist keine Methode sondern eine Funktion. Und die ist ein wenig lang und umständlich geschrieben:

Code: Alles auswählen

def get_sheet(filename):
    return open_workbook(filename).sheet_by_index(0)
Man muss ja nicht jedes Zwischenergebnis an einen eigenen Namen binden. Solange es nicht zu unübersichtlich wird und das Verständnis darunter leidet, kann man ruhig etwas mehr in einen Ausdruck stecken.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

BlackJack:Danke.Sie haben mir sehr geholfen.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

Das Auslesen von Tabelle ist nur ein Teil meiner Aufgabe.Bevor ich zum Ziel komme,muss ich noch ein paar Rätseln lösen und zwar weiter geht es mit der Interpolation innerhalb von der Tabelle.Das Problem ist hier die Matrix.Ich habe schon ein Beispiel gelöst,wenn ich der Volumenstrom als Funktion der Breite habe aber in meinem Beispiel ist der Volumenstrom nicht nur von der Breite sondern von der Höhe abhängig.Wie geht so was?Hier ist meine Funktion wenn VdotLiq=f(cellwidth):

Code: Alles auswählen

    def readVdotLiq(self, fileName):
        sh = self._getWorkBook(fileName)
        col = self._getPropertyCol('Width', sh)
        col2 = self._getPropertyCol('VdotLiq', sh)
        #vdotlist = []
        self.cellwidth = array([x for x in sh.col_values(col)[1:12] if x != ''])
        self.VdotLiq = array([x for x in sh.col_values(col2)[1:12] if x != ''])
        #
        self.tck = splrep(self.cellwidth,self.VdotLiq,k=3,s=0)
In meinem neuen Beispiel habe ich 3 Variablen:self.cellwidth,self.cellheight,self.VdotAir.Außerdem ist self.cellheigh eine Matrix und die Funktion sieht so:

Code: Alles auswählen

    def readVdotAir(self, fileName):
        
        sh = self._getWorkBook(fileName)

        start_column_index ,start_row_index = 2,2
        data_width, data_height = 11,11
        end_column_index = start_column_index + data_height
        end_row_index = start_row_index + data_width
        
        self.cellwidth = array([sh.col_values(start_column_index-1,start_row_index,\
        end_row_index)])
        self.cellheight = array([sh.row_values(start_row_index-1,start_column_index,\
        end_column_index)])
        
        self.VdotAir = matrix([sh.row_values(i ,start_column_index, end_column_index)\
        for i in xrange(start_row_index, end_row_index)])
        
        self.tck = splrep(self.cellwidth,self.VdotAir,k=3,s=0)
Es ist klar dass er schmeißt mir Fehler raus,weil self.cellwidth ein Vektor und self.VdotAir eine Matrix ist:

Code: Alles auswählen

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
    execfile(filename, namespace)
  File "C:/SVNRepo/branches/1.0/modules/measurementDataReader.py", line 250, in <module>
    op.readVdotAir('F://Masterthesis//Anstroemung_air.xls')
  File "C:/SVNRepo/branches/1.0/modules/measurementDataReader.py", line 122, in readVdotAir
    self.tck = splrep(self.cellwidth,self.VdotAir,k=3,s=0)
  File "C:\Python27\lib\site-packages\scipy\interpolate\fitpack.py", line 444, in splrep
    raise TypeError('Lengths of the first three arguments (x,y,w) must be equal')
TypeError: Lengths of the first three arguments (x,y,w) must be equal
Ich bin nicht sicher,dass das Programm vom Thema her noch dazu passt?
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

So ,ich habe in scipy die Funktionen,die solche Probleme in 2D-Bereich lösen gefunden:das sind bisplrep und bisplev.wenn ich schreibe:

Code: Alles auswählen

    def readVdotAir(self, fileName):
        
        sh = self._getWorkBook(fileName)

    #
        start_column_index ,start_row_index = 2,2
        data_width, data_height = 11,11
        end_column_index = start_column_index + data_height
        end_row_index = start_row_index + data_width
        
        self.cellwidth = array([sh.col_values(start_column_index-1,start_row_index,\
        end_row_index)])
        self.cellheight = array([sh.row_values(start_row_index-1,start_column_index,\
        end_column_index)])
        
        self.VdotAir = array([sh.row_values(i ,start_column_index, end_column_index)\
        for i in xrange(start_row_index, end_row_index)])
        
        self.tck = bisplrep(self.cellheight,self.cellwidth, self.VdotAir,kx=3, ky=3)
bekomme ich die Fehlermeldung:

Code: Alles auswählen

Imported NumPy 1.8.0, SciPy 0.13.3, Matplotlib 1.3.1
+ guidata 1.6.1, guiqwt 2.3.1
Type "scientific" for more details.
>>> runfile('C:/SVNRepo/branches/1.0/modules/measurementDataReader.py', wdir=r'C:/SVNRepo/branches/1.0/modules')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
    execfile(filename, namespace)
  File "C:/SVNRepo/branches/1.0/modules/measurementDataReader.py", line 250, in <module>
    op.readVdotAir('F://Masterthesis//Anstroemung_air.xls')
  File "C:/SVNRepo/branches/1.0/modules/measurementDataReader.py", line 122, in readVdotAir
    self.tck = bisplrep(self.cellheight,self.cellwidth, self.VdotAir,kx=3, ky=3)
  File "C:\Python27\lib\site-packages\scipy\interpolate\fitpack.py", line 868, in bisplrep
    raise TypeError('len(x)==len(y)==len(z) must hold.')
TypeError: len(x)==len(y)==len(z) must hold.
>>> 
Von der anderen Seite,ist das doch klar dass,wenn man in 2D-Bereich interpolieren will,liegt eine Matrix dazwischen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und? Dir ist natürlich klar was gemacht werden soll, aber die Funktion kann mit den übergebenen Werten nichts anfangen. Du musst sie schon so übergeben, wie sie von ihr erwartet werden. Welche Eigenschaft erwartet wird, dass sagt die Fehlermeldung ja nun mehr als deutlich.
Das Leben ist wie ein Tennisball.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

Die Fehlermeldung sagt,dass die ersten drei Elemenete der "bisplrep"-Funktion die gleiche Anzahl der Komponeneten haben sollen.wenn ich meine Matrix mit "reshape" in Vektor transformieren möchte,wird mein Vektor doppelt so groß,da die Tabelle die Werte in zwei Richtungen hat.
BlackJack

@anika_20: Die Tabelle muss halt quadratisch sein und nicht rechteckig, sonst geht das so nicht.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

BlackJack:Vielen Dank.Ich habe in Wirklichkeit eine quadratische Tabelle,nur zu Probe war sie anders.Ich habe sie schon geändert.
Es funktioniert auch.So sieht es momentan aus:

Code: Alles auswählen

    def readVdotAir(self, fileName):
        
        sh = self._getWorkBook(fileName)


        start_column_index ,start_row_index = 2,2
        data_width, data_height = 11,11
        end_column_index = start_column_index + data_height
        end_row_index = start_row_index + data_width
        
        self.cellwidth = array(sh.col_values(start_column_index-1,start_row_index,\
        end_row_index))
        self.cellheight = array(sh.row_values(start_row_index-1,start_column_index,\
        end_column_index))
        
        self.VdotAir = self.VdotAir = array([sh.row_values(i ,start_column_index, end_column_index)\
        for i in xrange(start_row_index, end_row_index)])
        x, y = meshgrid(self.cellheight, self.cellwidth)
        self.bitck = Rbf(x, y, self.VdotAir)
Vielleicht kann mir jemand noch helfen:gibt es Möglichkeit,dass Python die Anzahl der Zellen(data_width,data_height) automatisch erkennt oder geht das nur wenn man das manuell eingibt?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Ich kenne mich mit xlrd nicht aus, aber ich mache sehr viel mit gewrappten C++ Klassen in Python und vieles davon lässt sich wohl auch auf die Excel-Python Schnittstelle übertragen.
Am Ende Deiner Methode get_sheet wird geht die Variable book out-of-scope. Es könnte sein, dass Du dann Probleme bekommst auf ein sheet zuzugreifen, wenn das book gelöscht wurde. Probier mal ob es damit klappt:

Code: Alles auswählen

def get_sheet(fileName):
    book= open_workbook(fileName)
    sheet = book.sheet_by_index(0)        
    return book, sheet

def read_vdot_air(fileName):
    book, sheet = get_sheet(fileName)
    ...
a fool with a tool is still a fool, www.magben.de, YouTube
BlackJack

@MagBen: Welches Problem versuchst Du damit denn jetzt zu lösen? Die Funktion funktioniert doch so wie sie da steht.

Ich sehe auch nicht wieso das verschwinden des Namens `book` irgendwo ein Problem darstellen sollte. Entweder hat das `sheet`-Objekt alle Daten die es braucht, dann kann das `book`-Objekt ruhig zerstört werden. Oder es greift auf das `book`-Objekt zu wenn man Methoden auf dem `sheet` aufruft — in dem Falle hätte es aber selber noch eine Referenz auf das `book`-Objekt, denn sonst könnte es ja nicht darauf zugreifen. Und in dem Falle wird das `book`-Objekt auch nicht zerstört wenn der Name in der Funktion verschwindet.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@MegBen: xlrd ist eine reine Python-Bibliothek. Damit kann es nicht zu fehlerhaften Referenzen kommen, wie das bei Deinen C++-Geschichten vielleicht möglich ist. Das Problem war, dass die get_sheet-Methode von Workbook eine interne Methode ist, die ein Sheet lädt, und sobald das Sheet einmal geladen ist, mit einer Fehlermeldung abbricht. Der offizielle Weg über sheet_by_index hat diese Nebenbedingungen nicht.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

Hallo Leute, nochmals herzlichen Dank für die Hilfe.Habe momentan noch ein Problem, und zwar nachdem ich die Daten interpoliert habe, benutze ich sie für die weiteren Berechnungen.Nochmals zur Erinnerung,meine Funktion sieht so aus:

Code: Alles auswählen

    def readVdotAir(self, fileName):
        
        sh = self._getWorkBook(fileName)

        start_column_index ,start_row_index = 2,2
        data_width, data_height = 6,6
        end_column_index = start_column_index + data_height
        end_row_index = start_row_index + data_width
        
        self.cellwidth = array(sh.col_values(start_column_index-1,start_row_index,\
        end_row_index))
        self.cellheight = array(sh.row_values(start_row_index-1,start_column_index,\
        end_column_index))
        
        self.VdotAir =  array([sh.row_values(i ,start_column_index, end_column_index)\
        for i in xrange(start_row_index, end_row_index)])
        #
        x, y = meshgrid(self.cellheight, self.cellwidth)
        self.bitck = Rbf(x, y, self.VdotAir)
    
Weiter geht es mit der Berechnung von Wärmeübergang in einem Wärmetauscher, der aus der unterschiedlichen Anzahl der Zellen bestehen kann.Die Anzahl der Zellen in den unterschiedlichen Richtungen(x,y,z) wird als nDepth,nHeight,nWidth definiert. Wie es schon aus früheren Berechnungen klar ist, habe ich Luft- und Flüssigkeitsseite.Die Eintrittsdaten,wie Volumen(VdotAirCell oder VdotLiqCell) werden mit der Klasse 'operationData' abgelesen.Weiter geht es mit der Schleife, in der die Zellennummern berechnet werden.Un dann werden die Volumina in einzelnen Zellen berechnet.Hier sieht man,dass 'VdotAirCell' bitck-Funktion benutzt,die früher definiert wurde.(siehe oben).

Code: Alles auswählen

    def calculateHeatTransfer(self, model, operationData):

        VdotAirCell = operationData.VdotAir/(self.nWidth*self.nHeight)
        VdotLiqCell = operationData.VdotLiq/(self.nDepth*self.nWidth)
        tAirInCell = operationData.tAirIn
        tLiqInCell = operationData.tLiqIn 
        jTeilung = 1./self.nWidth
        kTeilung = 1./self.nWidth

        cellOp = []
            
        Q = 0.                        
        for i in range(self.nDepth):
            for j in range(self.nWidth):
                jcell = (j + 0.5)*jTeilung
                for k in range(self.nHeight):
                    kcell = (k + 0.5)*kTeilung
                    print 'kcell',kcell
                    
                    print i,j,k, i*self.nHeight*self.nWidth + j*self.nHeight + k
               
                    
                    # initialise operation data
                    cellOp.append(deepcopy(operationData))

                    # set boundary values for air
  
                    if (i - 1) < 0:
                        tAirIn = tAirInCell
                        VdotAirCell = operationData.bitck(kcell,jcell)/(self.nHeight*self.nWidth)
                    
                        if VdotAirCell < 0.:
                            VdotAirCell = 0.
                       
                            
                        print 'VdotAirCell',VdotAirCell
Mein Problem ist,dass wenn ich mit mehreren Zellen berechne,macht er alles richtig.Ich vergleiche mit einem kompletten Wärmetauscher,der die gleiche Eigenschaften hat, aber die andere Funktion benutzt.Wenn ich aber nur eine Zelle habe,berechnet er absolut falsch.Ich weiß,dass es nicht so einfach ist, aber vielleicht hat jemand eine Idee,wie man so was löst?
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

Ich habe mittlerweiler golgendes probiert:wenn ich für den Wärmetauscher mit (nDepth = 1, nWidth = 1, nHeight = 1) statt

Code: Alles auswählen

VdotAirCell = operationData.bitck(jcell,kcell)/(self.nHeight*self.nWidth)
folgendes eingebe:

Code: Alles auswählen

VdotAirCell = 4.4
berechnet er richtig.4.4 ist der mittlere Volumenstrom.
Damit es ein wenig klarer ist, stelle ich meine Tabelle raus:

Code: Alles auswählen

   Width                          	VdotAir					
     Height		0	            0,2	             0,4	            0,6	             0,8	              1
	0	4,308064365	4,922172892	5,154789758	4,950086916	4,549985906	4,615118628
	0,2	4,736079399	5,192008457	4,391806436	4,401111111	5,164094433	4,661642001
	0,4	4,875649518	4,549985906	1,498052619	1,888848955	4,680251351	4,987305614
	0,6	4,912868217	4,540681231	1,591099366	1,172389006	4,522071882	4,940782241
	0,8	4,6988607	        5,201313131	4,308064365	 4,261540991	5,089657035	4,810516796
	1	4,615118628	4,6988607	        4,847735494	5,219922481       5,005914964	4,41041578 

Im Fall (nDepth = 1, nWidth = 1, nHeight = 1) zeigt er mir VdotAirCell = 0.23790615307.Ich verstehe das nicht wie interpoliert er?
Wenn ich das hier betrachte:

Code: Alles auswählen

       
for i in range(self.nDepth):
            for j in range(self.nWidth):
                jcell = (j + 0.5)*jTeilung
                
                for k in range(self.nHeight):
                    kcell = (k + 0.5)*kTeilung
ist mein jcell= (j + 0.5)*jTeilung= (0+0.5)*1/1=0.5 da jTeilung = 1./self.nWidth
und kcell = (k + 0.5)*kTeilung= (0+0.5)*1/1 =0.5 da kTeilung = 1./self.nWidth
ist Height = 0.5 und Width = 0.5 muss der Wert zwischen 1,498052619 1,888848955
1,591099366 1,172389006 liegen.
warum gibt er mir VdotAirCell = 0.23790615307 aus.Absolut unklar.
ich versuche die Tabelle im deutlichen Format zu speichern,die letzten zwei Zeilen rutschen nach rechts.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

Hallo Leute,ich bitte nochmal um die Hilfe. ich habe in meiner letzten Aufgabe immer noch kein Fehler gefunden.Ich habe kurze Ferien gahabt, aber das Problem muss ich noch lösen.Ich versuche es noch einmal,vielleicht kann mir jemand helfen. Mit def readVdotAir lese ich meine Daten aus der Excel-Tabelle ab:

Code: Alles auswählen

    def readVdotAir(self, fileName):
        
        sh = self._getWorkBook(fileName)

        start_column_index ,start_row_index = 2,2
        data_width, data_height = 6,6
        end_column_index = start_column_index + data_height
        end_row_index = start_row_index + data_width
        
        self.cellwidth = array(sh.col_values(start_column_index-1,start_row_index,\
        end_row_index))
        self.cellheight = array(sh.row_values(start_row_index-1,start_column_index,\
        end_column_index))
        
        self.VdotAir =  array([sh.row_values(i ,start_column_index, end_column_index)\
        for i in xrange(start_row_index, end_row_index)])
        #
        x, y = meshgrid(self.cellheight, self.cellwidth)
        print 'x,y',x,y
        self.bitck = Rbf(x, y, self.VdotAir)
    
Dann werden die interpolierten Daten durch Anzahl der Zellen dividiert:

Code: Alles auswählen

 if (i - 1) < 0:
                        tAirIn = tAirInCell
                        VdotAirCell = operationData.bitck(jcell,kcell)/(self.nHeight*self.nWidth)
(i-1) bedeutet hier nur das nur die Eintrittsdaten aus der Excel-Tabelle interpoliert werden müssen.
Was stimmt nicht?Kann man überhaupt mit Rbf interpolieren?
Danke für die HIlfe
BlackJack

@anika_20: Ich denke das Problem was man als helfender hier hat, ist das es a) etwas umfangreicher ist sich hier einzuarbeiten, und b) Wissen jenseits von Python nötig ist um die Frage zu beantworten. Und zwar Wissen aus der Physik und auch mathematische Hintergründe.
anika_20
User
Beiträge: 23
Registriert: Donnerstag 5. Juni 2014, 09:21

BlackJack:Guten Morgen,
BlackJack welche Möglichkeiten gibt es außer Rbf innerhalb der Matrix zu interpolieren?In meinem Programm:

Code: Alles auswählen

x, y = meshgrid(self.cellheight, self.cellwidth)
        self.bitck = Rbf(x, y, self.VdotAir)
Meshgrid gibt mir Koordinatenmatrizen aus zwei oder mehr Koordinatenvektoren zurück und Rbf-interpoliert in dem Bereich.Aber welche Möglichkeiten gibt es noch in so einem Feld zu interpolieren?
Danke
BlackJack

@anika_20: In dem Modul aus dem `Rbf()` kommt, gibt es auch noch andere Funktionen.
Antworten