float(1) durch int(1) in liste ersetzen

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
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Hallo,

ich möchte gerne in meiner Liste an aus einer float(1) eine int(1) machen. Leider funktioniert dies nicht so zusammen mit meinem Dictionary wie ich erhofft hatte, wie im Beispiel mit der Liste x. Wo liegt da der Fehler?

Code: Alles auswählen

import numpy as np

an=[6,1]
print an

radiusdic = {1: 25.0, 6: 70.0} #{atomic number: radius}
for i in range(0,len(an)):#replace atomic number by atomic radius
    if an[i] in radiusdic:
        an[i] = radiusdic[an[i]]
an = an/np.max(an) #normalize
print an

for i in range(0,len(an)): #replace float(1) by int(1)
    if an[i] == float(1):
        print an[i]
        an[i] = int(1)
        print an[i]
print an #doesn't work

print '--------'

x = [1.,2.,3.,4.] #works
for i in range(0,len(x)):
    if x[i] == float(1):
        x[i] = int(1)
print x
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Das hat nichts mit dem dict zu tun, sondern damit, daß Du versuchst unterschiedliche Typen in ein numpy.ndarray zu stecken.

Im Übrigen gehen manche Operationen um Einiges einfacher. Nur mal als Beispiel:

Code: Alles auswählen

In [3]: radii = {1: 25.0, 6: 70.0}

In [4]: an = [r for n, r in sorted(radii.iteritems())]
Den Rest überlasse ich Dir fürs Erste ;-).

Wieso willst Du Integer an der Stelle? Du solltest außerdem bedenken, daß 1 == int(1). Also kannst Du auch schreiben an = 1. Das allerdings ist auch rel. kompliziert ausgedrückt, denn wenn Du wirklich einen Index brauchst geht auch:

Code: Alles auswählen

for index, value in enumerate(iterable):
Aber auch das brauchst Du eigentlich nicht, denn numpy.where und Konsorten bieten Dir einfache Selektionsalternativen. Dann aber wieder: Zwei versch. Typen in einem ndarray ...

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

PS Wenn der Radius in Pikometern bzgl. Genauigkeit à la Wikipedia ausreichend genau ist, kannst Du natürlich auch von Anfang an Integer verwenden.
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Danke schonmal für die Antwort. Hintergrund ist die Visualisierung von Molekülen und speziell hier das vierte Argument s in mlab.points3d(x,y,z,s) [1] für die Größe der Kugeln. Wenn ich das richtig ausprobiert habe, dann muß das array s die Form haben, daß eine 1 als Integer drin ist und entsprechend Dezimalzahlen kleiner 1.

[1] from enthought.mayavi import mlab
Zuletzt geändert von mushroom am Montag 8. August 2011, 20:45, insgesamt 1-mal geändert.
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

CM hat geschrieben:Das hat nichts mit dem dict zu tun, sondern damit, daß Du versuchst unterschiedliche Typen in ein numpy.ndarray zu stecken.
Mein array wird ja scheinbar durch die Zeile

Code: Alles auswählen

an = an/np.max(an) #normalize
zu einem numpy.ndarray. Gibt es denn eine Möglichkeit mein array wieder zu ent-numpysieren?

Nachtrag: Habe nochmal ein wenig rumprobiert und dabei gesehen, daß mein voriger post Unsinn ist. Verstehe dann aber in meinem folgenden Code nicht, warum die H-Atome (Radius 25 im an-array) nicht gezeichnet werden.

Code: Alles auswählen

from enthought.mayavi import mlab

x = [0.0,0.5]
y = [0.0,0.5]
z = [0.0,0.5]
an = [70, 25]
mlab.points3d(x, y, z, an, color=(1,0.5,1))
mlab.show()
BlackJack

@mushroom: Warum willst Du das tun? Ob Du da ein Array mit Gleitpunktzahlen übergibst, oder eine Liste mit den gleichen Gleitpunktzahlen bei denen die 1.0en durch Ganzzahl 1en ersetzt sind, macht keinen Unterschied. Wichtig sind die Werte und nicht die Typen, und da gilt ``1 == 1.0``.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hinweis: Du solltest mit den Einheiten aufpassen: Deine Radien: Pikometer. Deine Displazierung im karthesischen Raum *wahrscheinlich* Nanometer oder Ångström. Je nachdem, was Du erreichen willst, werden Deine Moleküle mit den Radien ziemlich nackisch aussehen.

Und: Abgesehen davon, daß es bestimmt eine schöne Übung ist - Du weißt, daß es eine ganze Reihe von Mol.-Graphics-Viewern gibt? U. a. in Python?

Zu Deiner "versteckter Punkt"-Frage: Das ist in der Doku in der Tat etwas versteckt:

Code: Alles auswählen

mlab.points3d(x, y, z, an, color=(1,0.5,1), scale_factor = 1)
sollte das Problem beseitigen.

Wenn die Atome eine unterschiedliche Farbe haben sollen, empfiehlt sich ggf. eine eigene colormap.

HTH
Christian

edit: Das mit den Einheiten ist natürlich geraten.
Zuletzt geändert von CM am Dienstag 9. August 2011, 08:01, insgesamt 1-mal geändert.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

PS

Ach, und bzgl. "ent-numpysieren": Numpy-Arrays haben eine tolist-Methode. Also:

Code: Alles auswählen

an.tolist()
Aber wie BJ schrieb ist das überhaupt nicht nötig. Und andererseits würde eine ListComprehension das "numpysieren" überflüssig machen.

Und: Wieso gleich kommst Du auf die Idee, dass da irgendwo eine 1 stehen muß?
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Numpy-arrays können übrigens auch ihren Typ ändern:

Code: Alles auswählen

>>> import numpy
>>> a = numpy.array([1.1, 1.2, 1.3])
>>> a
0: array([ 1.1,  1.2,  1.3])
>>> a.dtype
1: dtype('float64')
>>> a.astype("int32")
2: array([1, 1, 1])
BlackJack

@HerrHagen: Das ist aber etwas missverständlich formuliert, da Du nicht den Typ von dem Array geändert hast, sondern ein neues Array mit einem anderen Typ erstellt hast, in das die Werte aus dem Alten übertragen und dabei umgewandelt wurden.

Code: Alles auswählen

In [40]: a = np.array([1.1, 1.2, 1.3])

In [41]: b = a.astype('int32')

In [42]: a is b
Out[42]: False
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

@BlackJack, CM Bezüglich der Ersetzung von floats durch ints war ich einem Irrtum aufgesessen. Das hat sich erledigt.

@CM Jep, weiß daß es einige Viewer gibt :-) Den Viewer den ich mir bastel, ist Teil ein größeren Programms, daß automatisch Ergebnisse aus quantenchemischen Rechnungen aufarbeitet.
Die colormap kommt noch. :-)
Danke für den Hinweis mit den Einheiten, ist mir gar nicht mehr aufgefallen. Die Geometriedaten liegen tatsähclich in Angstrom vor und die Radien in Pikometern.

Problem ist jetzt nicht mehr meine ursprüngliche Fragestellung, sondern das, was ich im Post #5 geschrieben habe. Werde dafür aber einen neuen Thread aufmachen.

Danke für eure Hilfe.
Grüße
Markus
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ich habe mal bei einem Simulationsprogramm Radius und Durchmesser verwechselt und dann geschlagene 2 Wochen gerätselt, warum meine Ergebnisse ganz ok, aber immer um den Faktor 4 daneben waren (als ich den Fehler gefunden hatte, hatten die Kollegen ihren Spaß :evil: ). Beim aktuellen Projekt (allerdings in C++) schreibe ich eine expliziete Einheitentabelle in den Code (separate Datei), damit so etwas nicht mehr vorkommt und nicht irgendwelche komischen Konversionskonstanten in den Rechnungen rumfliegen, die ich nach ein paar Wochen sowieso nicht mehr verstehe. Vielleicht eine Idee für Dich?
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

CM hat geschrieben:
Zu Deiner "versteckter Punkt"-Frage: Das ist in der Doku in der Tat etwas versteckt:

Code: Alles auswählen

mlab.points3d(x, y, z, an, color=(1,0.5,1), scale_factor = 1)
sollte das Problem beseitigen.
Sorry, habe erst jetzt deinen post aufmerksam durchgelesen. Damit hat sich das Problem ja auch erledigt. Habe da auch noch eine andere Lösung gefunden:

Code: Alles auswählen

pts = mlab.points3d(x, y, z, s)
pts.glyph.glyph.clamping = False

Die Radien habe ich auch in einer separaten Textdatei ausgelagert. Falls da mal was geändert werden soll, dann geht das da deutlich einfacher.
Antworten