Rechenoperationen mit numpy.float64

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.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Hallo,

ich habe ein Programm in dem folgende Rechnungen ausgeführt werden sollen:

Code: Alles auswählen

deltaX = x[m+1] - x[m]
deltaY = y[n] - y[n+1]
allerdings bekeomme ich einen Fehler:
4380500.0 4380300.0
Inappropriate argument type.
unsupported operand type(s) for -: 'numpy.float64' and 'numpy.float64'
die beiden Zahlen entsprechen übrigens x[m+1] und x[m].

Ich habe numpy installiert und importiert mit
from numpy import *
from numpy import array
import numpy as Numeric
import numpy as numpy
Numeric.Int = Numeric.int32
Numeric.Float = Numeric.float64
Muss ich noch mehr aus numpy importieren oder die Typen umwandeln?

Danke und Grüße
Michael
Python rockt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

das kann ich so nicht nachvollziehen:

Code: Alles auswählen

>>> from numpy import *
>>> x = array([4380500.0], dtype = float64)
>>> y = array([4380300.0], dtype = float64)
>>> a = x-y
>>> a
array([ 200.])
>>> a.dtype
dtype('float64')
Aber Deine Importe sind etwas seltsam ... Du importierst erst * von numpy und dann nochmal "array"? Das ist nicht notwendig. Aber wenn Du tatsächlich Numeric und numpy in einem Modul nutzen willst, würde ich diese beiden Module explizit ansprechen, wie in Zeile 3 und 4 Deiner Importe gezeigt.

Magst Du uns bitten den ganzen Traceback und das relevante Codestück zeigen, in dem man sie wie x und y generiert werden?

Gruß,
Christian

edit: PS Es geht natürlich auch

Code: Alles auswählen

a = x[0] - y[0]
bei mir, was Deinem Aufruf etwas eher entspricht ... .
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Wow, toll, Danke für schnelle Antwort. Klar, vielleicht können wir das lösen. Leider nicht mein Code und kommerziel genutzt, daher muss ich wohl Einschränkungen machen.

Code: Alles auswählen

....
....
...
.
                    if not self.inactiveFringeMap[(m,n)]:
                        # go for diagionals if no direkt (N, E, S, W) neighbours exist
                        # up left
                        #print self.activeWide[m-1, n-1]
                        #print self.activeWide[m+1, n-1]
                        #print self.activeWide[m+1, n+1]
                        #print self.activeWide[m-1, n+1]
                        if m > 0 and n > 0 and self.activeWide[m-1, n-1]:
                            deltaX = x[m] - x[m-1]
                            deltaY = y[n-1] - y[n] 
                            distance = math.sqrt(deltaX * deltaX + deltaY * deltaY)
                            self.inactiveFringeMap[(m,n)].append(((m-1, n-1), distance))
                        # up right
                        if m < maxN and n > 0 and self.activeWide[m+1, n-1]:
                            deltaX = x[m+1] - x[m]
                            deltaY = y[n-1] - y[n] 
                            distance = math.sqrt(deltaX * deltaX + deltaY * deltaY)
                            self.inactiveFringeMap[(m,n)].append(((m+1, n-1), distance))
# --->                  # down right
                        if m < maxN and n < maxN and self.activeWide[m+1, n+1]:
                            deltaX = x[m+1] - x[m]
                            deltaY = y[n] - y[n+1]
                            distance = math.sqrt(deltaX * deltaX + deltaY * deltaY)
                            self.inactiveFringeMap[(m,n)].append(((m+1, n+1), distance))
                        # down left
                        if m > 0 and n < maxN and self.activeWide[m-1, n+1]:
                            deltaX = x[m] - x[m-1]
                            deltaY = y[n+1] -y[n] 
                            distance = math.sqrt(deltaX * deltaX + deltaY * deltaY)
                            self.inactiveFringeMap[(m,n)].append(((m-1, n+1), distance))
                    if self.inactiveFringeMap[(m,n)]:
                        distanceSum = 0
                        for value in self.inactiveFringeMap[(m,n)]:
                            distanceSum += value[1]
                        newValue = []
                        for value in self.inactiveFringeMap[(m,n)]:
                            newValue.append((value[0], value[1]/distanceSum))
                        self.inactiveFringeMap[(m,n)] = newValue
                    else:
                        del self.inactiveFringeMap[(m,n)]
Abbruch passiert in Zeile 26 (siehe Code oben), im Original in Line 372 natürlich! Leider ist es eine Riesendatei und ein Riesenproject mit etwa 15 Pythondateien, kann nicht alles posten.

Code: Alles auswählen

 #### Modellsteuerung #################################################
 called from gw_kopp.cpp, now loading gw.py
 + now using mf2000exe.py . . .
 init Modflow
 init Exchange

 Modflow gestartet
 setting IDs
...
Inappropriate argument type.
unsupported operand type(s) for -: 'numpy.float64' and 'numpy.float64'
 line 161 in setIDs in file xxx.py
 line 67 in __init__ in file \yyyy.py
 line 372 in makeInactiveFringeMap in file \yyyy.py
Methode setIDs konnte nicht ausgefuehrt werden.
Zuletzt geändert von mod_che am Donnerstag 10. Mai 2007, 17:10, insgesamt 3-mal geändert.
Python rockt.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Zur Erstellung von x und y noch:

X und Y werden aus einer VMG-Reader Klasse importiert, also auf einer Datenaustauschdatei, da ich mit zwei Modellen rechne un diese zwischendurch Daten tauschen. X und Y sind dabei Koordinaten, sozusagen auf der Landkarte.

In Datei stehen eben Werte wie
4380000.000000
4380200.000000
4380400.000000
4380600.000000
4380800.000000
...
welche dann in x und y Array eingelesen werden, mit readlines()
Zuletzt geändert von mod_che am Freitag 11. Mai 2007, 16:39, insgesamt 1-mal geändert.
Python rockt.
BlackJack

Sehr merkwürdiger Fehler. Kann ich auch nicht nachvollziehen:

Code: Alles auswählen

In [30]: x = numpy.array([4380500.0, 4380300.0], dtype=numpy.float64)

In [31]: x[0] - x[1]
Out[31]: 200.0

In [32]: type(_)
Out[32]: <type 'numpy.float64'>
Nur mit der Fehlermeldung hätte ich vermutet, dass es zwei verschiedene `numpy.float64` Typen in dem Programm gibt, aber da beide Werte aus dem *gleichen* `array` kommen, kann man das wohl ausschliessen.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Dennoch, was passiert, wenn Du entweder Numeric oder numpy wegläßt? Ich frage mich immer noch von welchem Typ diese Arrays sind. Klingt blöde, aber tritt irgendwo eine Konvertierung von numpy zu Numeric oder umgekehrt auf? Vielleicht nicht explizit, sondern implizit? Deswegen vielleicht mal mit den Importen rumspielen. Ich will einfach nicht so recht glauben, daß beide Module notwendig sind.
mod_che hat geschrieben:Leider ist es eine Riesendatei und ein Riesenproject mit etwa 15 Pythondateien, kann nicht alles posten.
Klar, dafür haben wir Verständnis, aber Du siehst bestimmt auch, daß ohne ein vollständiges Traceback und ohne relevanten Code (was auch immer das im Einzelfall ist) nur geraten werden kann.

Gruß,
Christian
BlackJack

`Numeric` wird doch gar nicht importiert. Zumindest in dem Stück was hier gepostet wurde, ist das nur ein anderer Name für `numpy`.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Hallo,
zur späten Stunde noch ein Hinweis zur Lösung des Problems. Die Dateien gibt es schon eine Weile und wurden damals mit Numeric programmiert. Aus irgendeinem Grund wurde damals alles in der Form Numeric.befehl benutzt. Also zB numeric.array(). Nun haben wir - in Blick auf die Zukunft - Numeric gelöscht und nutzen numpy. Daher die Einsetzung "import numpy as Numeric", was ja meiner Meinung nach wirklich nur eine Namenskonvention ist (,oder?). So müssen wir den Code nicht an zahlreichen Stellen ändern. Naja, wäre auch machbar mit Search/Replace, wurde mir aber so vorgelegt, whatever.
Ich benutze also aktuell NUR numpy, und KEIN Numeric mehr. Ich hoffe das hilft Euch.

Wie ich noch mehr mit den Importen rumspielen kann verstehe ich jetzt nich ganz. Ich werde aber morgen im Büro rumprobieren und auch nochmal rausbekommen wie x und y hergestellt werden. Es ist wirklich leider so, dass es hier um Verweise aus 4-5 py-Dateien geht und dazu noch Schreib- und lesebefehle aus netCDF Dateien kommen, daher ist es auch für mich gerade nicht so leicht nachvollziehbar, wie diese Variablen initiiert werden...

Morgen mehr... Danke für alles, Gute Nacht.
Michi
Python rockt.
BlackJack

Interessant wäre es die Typen der beteiligten Objekte anzuschauen. Behandle die Ausnahme mal selbst:

Code: Alles auswählen

# --->                  # down right 
                        if m < maxN and n < maxN and self.activeWide[m+1, n+1]:
                            try:
                                deltaX = x[m+1] - x[m]
                            except TypeError:
                                print '-' * 40
                                print type(x)
                                type_a, type_b = map(type, (x[m + 1], x[m]))
                                print type_a, type_b, type_a is type_b
                                print '-' * 40
                                raise
Was wird da ausgegeben?
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Code: Alles auswählen

----------------------------------------
<type 'numpy.ndarray'>
<type 'numpy.float64'> <type 'numpy.float64'> True
----------------------------------------
Inappropriate argument type.
unsupported operand type(s) for -: 'numpy.float64' and 'numpy.float64'
 line 161 in setIDs in file \gw.py
 line 71 in __init__ in file \mf2000\mf2000exe.py
 line 380 in makeInactiveFringeMap in file \mf2000\mf2000exe.py
Aha, Danke für den Tipp, ich werde nicht ganz schlau daraus, vielleicht kann ich noch mehr über die Gernerierung von X und Y herausfinden. Hilft das hier vielleicht:


Code: Alles auswählen

class VMGReader:
    def __init__(self, vmgFileName):
        f = open(vmgFileName)
        self.data = f.readlines()
        f.close()
        self.data = [x.split() for x in self.data]
        self.numberOfColumns = int(self.data[0][0])
        self.numberOfRows = int(self.data[2 + self.numberOfColumns][0])
        self.numberOfLayers = int(self.data[4 + self.numberOfColumns + self.numberOfRows][0])
    def readX(self):
        self.x = []
        for line in self.data[1:2+self.numberOfColumns]:
            self.x.append(float(line[0]))
    def readY(self):
        self.y = []
        for line in self.data[3 + self.numberOfColumns : 4 + self.numberOfColumns + self.numberOfRows]:
            self.y.append(float(line[0]))
    def readZ(self):
        self.z = []
        for line in self.data[5 + self.numberOfColumns + self.numberOfRows :
                         6 + self.numberOfColumns + self.numberOfRows + self.numberOfLayers]:
            self.z.append(float(line[0]))
    def readActive(self):
        """
        reads active array of upper layer
        """
        self.active = Numeric.zeros((self.numberOfColumns, self.numberOfRows))
        offset = self.numberOfColumns + self.numberOfRows + \
                 self.numberOfLayers + 7 + (self.numberOfLayers -1) * (self.numberOfRows + 1)
        n = 0
        for line in self.data[offset : offset+self.numberOfRows]:
            m = 0
            for value in line:
                self.active[m ,n] = int(value)
                m += 1
            n += 1
Dies ist aus der Datei, welche aus der oben genannten Datei liest. In der Datei steht jeweils ein Zahlenwert pro Zeile.
Python rockt.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

OK, scheinbar ist X vom Type ndarray, die Zähler in den [] aber floats? Bzw. die Zusammensetzung x[m+1] ergibt dann einen Float? Also, müsste ich was Konvertieren, oder?

Habe dazu das gefunden: http://projects.scipy.org/pipermail/sci ... 06083.html

Meine Import konnte ich verringern ohne bis zur aktuellen Fehlermeldung eine weitere zu sehen:

Code: Alles auswählen

    import numpy as Numeric
    import numpy as numpy
    Numeric.Int = Numeric.int32
    Numeric.Float = Numeric.float64
PS: Was mir beim Lesen jetzt öfters aufgefallen ist: Viele Leutz meinen, dass "import module_xyz" besser sei als "from module_xyz import *"? Ist das so, kann man das so sagen? Komischerweise hatte ich immer mit "from... import *" mehr Erfolg!

Grüße aus Berlin
Python rockt.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Ok, ich schon wieder. Hier nochmals einige Versuche, welche im Python Shell ausgeführt habe. Funktioniert alles gut!

Code: Alles auswählen

>>> import numpy
>>> from numpy import array
>>> a = numpy.array([1.0,2.0,3.0,4.0,5.0])
>>> a
array([ 1.,  2.,  3.,  4.,  5.])
>>> print type(a[1])
<type 'numpy.float64'>
>>> x = 3
>>> y = 2
>>> c = a[y] + a[x]
>>> c
7.0
>>> type(c)
<type 'numpy.float64'>
>>> type(x)
<type 'int'>
>>> type(a)
<type 'numpy.ndarray'>
>>> a[y], a[x], c, y, x, a
(3.0, 4.0, 7.0, 2, 3, array([ 1.,  2.,  3.,  4.,  5.]))
>>> map (type, (a[y], a[x], c, y, x, a))
[<type 'numpy.float64'>, <type 'numpy.float64'>, <type 'numpy.float64'>, <type '
int'>, <type 'int'>, <type 'numpy.ndarray'>]
>>>
Python rockt.
BlackJack

Zu [wiki]Import[/wiki] solltest Du wie Wikiseite mal lesen.

Und den *-Import solltest Du möglichst nicht verwenden. Wenn der alte Quelltext kein `numpy` und keine *-Imports benutzt, dann solltest Du möglichst nur ``import numpy as Numeric`` schreiben und in den Namensräumen die minimalsten Änderungen vornehmen, die nötig sind.

Nach der Ausgabe von der Ausnahmebehandlung bin ich übrigens echt ratlos. Insbesondere das `True` zeigt, dass beide Werte wirklich den selben Typ haben und nicht unterschiedliche Typen, die nur ungünstigerweise gleiche Namen haben. Da *muss* Subtraktion möglich sein. Sehr eigenartig.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Und nu?
Python rockt.
BlackJack

Die Mailingliste vom `numpy`-Projekt in Anspruch nehmen falls hier niemand mehr eine Idee hat.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

BlackJack hat geschrieben:`Numeric` wird doch gar nicht importiert. Zumindest in dem Stück was hier gepostet wurde, ist das nur ein anderer Name für `numpy`.
Jou, war Blödsinn: x-mal hingeguckt und dann nicht mehr gesehen, was eigentlich abgeht ...
mod_che hat geschrieben:Habe dazu das gefunden: http://projects.scipy.org/pipermail/sci ... 06083.html
Verstehe nicht was das mit Deinem Problem zu tun hat: Hierbei geht um Inputparameter für Scipy-Funktionen. Ein Problem was übrigens mittlerweile gelöst ist (jedenfalls in svn).
mod_che hat geschrieben:OK, scheinbar ist X vom Type ndarray, die Zähler in den [] aber floats? Bzw. die Zusammensetzung x[m+1] ergibt dann einen Float? Also, müsste ich was Konvertieren, oder?
Nein, die Konvertierung ist implizit. Das sollte keine Fehlermeldung geben (u. U. aber ein nicht erwünschtes Ergebnis). Wie aber sieht X.shape aus? Und wie Y.shape?

Gruß,
Christian
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

PS Habe gerade etwas länger geschrieben und wurde unterbrochen, deshalb habe ich eure letzten Posts auch erst jetzt gesehen: Das Programm ist kommerziell, oder? Dann sollte es dafür eigentlich auch entsprechenden Support geben.

Gruß,
Christian

PPS Dennoch wüßte ich noch gerne - als letzte Idee - was .shape dieser beiden arrays ist.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Kann man an die eMail-Adresse, welche auf der numpy-Seite gelistet ist, einfach so eine Mail schreiben oder muss man sich irgendwie anmelden?
Python rockt.
mod_che
User
Beiträge: 46
Registriert: Freitag 13. April 2007, 16:58

Hi Christian,
auch Dir nochmals Danke für die Hilfe und das Mitdenken!

Hier deine ShapeInfos:

Code: Alles auswählen

len x <type 'numpy.ndarray'> 252
len y <type 'list'> 137
x.shape: (252,)
######################################################################
type x <type 'numpy.ndarray'>
type_a, type_b <type 'numpy.float64'> <type 'numpy.float64'> True
######################################################################
Inappropriate argument type.
unsupported operand type(s) for -: 'numpy.float64' and 'numpy.float64'
y.shape funktioniert ja logischerweise nicht, da y vom Typ 'list' ist, was mich jetzt auch wieder etwas wundert. Auf jeden Fall ist len(x) ungleich len(y), aber das kann ja passieren. Es handelt sich sozusagen um eine Area für Grundwassermodellierung, also einen Layer mit Ausweitung x und y in zwei Richtungen. Dieser Layer ist eben nicht immer quadratisch, daher macht das schon Sinn. Wieso aber einmal array und einmal list, keine Ahnung, werde am Ball bleiben und habe auch schon mal eine Mail an numpy-mailingList geschrieben.

Bis bald...
Python rockt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

mod_che hat geschrieben:Kann man an die eMail-Adresse, welche auf der numpy-Seite gelistet ist, einfach so eine Mail schreiben oder muss man sich irgendwie anmelden?
Du kannst jederzeit eine Mail an die Liste schreiben, aber wenn Du sie auch lesen willst, mußt Du dich anmelden: http://www.scipy.org/Mailing_Lists

Ehrlich gesagt: Ich habe auch keine Ahnung mehr, was da vorgeht. Allerdings habe ich noch keine Mail von Dir auf der numpy-Mailingliste gesehen. Hast Du tatsächlich schon an die Liste geschrieben?

Gruß,
Christian
Antworten