Tupel to float

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
Gerhardus
User
Beiträge: 42
Registriert: Dienstag 31. Dezember 2013, 01:59

Hallo,

Gibt es eine elegantere Möglichkeit aus einer Zahl, die als Tupel vorhanden ist, in
eine Floatzahl umzuwandeln.
z.B.: tup=(1.234,56)
Mein Ansatz:

Code: Alles auswählen

def tup2float(tup):
	if type(tup)==tuple:
		x=str(tup[0]).replace('.','')
		return float(x+'.'+str(tup[1]))
Eine Bank liefert teilweise solche csv Daten.
Gruß Gerhardus
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

Du versuchst nachtröglich etwas zu reparieren, was Du eigentlich schon beim Einlesen der Daten hättest richtig machen müssen.
Wie sehen die Dateien aus und wie versuchst Du sie zu lesen?
Benutzeravatar
__blackjack__
User
Beiträge: 13123
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Gerhardus: Das klingt nicht plausibel. Es ist wohl eher so, dass das Trennzeichen da nicht das Komma ist, sondern beispielsweise das Semikolon. Wie kommt denn das Tupel tatsächlich zustande? *Da* sollte man ansetzen, gar nicht erst so was komisches zu erzeugen, dann muss man das nicht hinterher so hässlich wieder geradebiegen.

Man macht keine Typprüfungen mit `type()`. Falls überhaupt mit `isinstance()`. Aber auch das macht man nicht. Es macht auch nicht so wirklich Sinn, denn falls das Argument kein Tupel ist, gibt die Funktion ein implizites `None` zurück.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

Gerhardus hat geschrieben: Freitag 11. März 2022, 22:27 Hallo,

Gibt es eine elegantere Möglichkeit aus einer Zahl, die als Tupel vorhanden ist, in
eine Floatzahl umzuwandeln.
z.B.: tup=(1.234,56)
Mein Ansatz:

Code: Alles auswählen

def tup2float(tup):
	if type(tup)==tuple:
		x=str(tup[0]).replace('.','')
		return float(x+'.'+str(tup[1]))
Eine Bank liefert teilweise solche csv Daten.
Das Python-Modul "csv" liest, aus offensichtlichen Gründen, natürlich nur Strings (ja, gegebenenfalls auch in Tupeln) und natürlich keine Tupel. Und um Strings locale-abhängig in floats zu wandeln, hat Python ein Modul namens "locale" an Bord... Viel Erfolg! ;-)
Gerhardus
User
Beiträge: 42
Registriert: Dienstag 31. Dezember 2013, 01:59

Hallo,

zu meiner eigentlichen Frage, ob es eine bessereLösung gibt folgendes:
auf einer Website: Tupel in float-Wert konvertieren, fand ich folgende Lösung:

Code: Alles auswählen

tupel=(3,45)
res=float('.'.join(str(ele) for ele in tupel)
Nur leider funktioniert das nicht mit Tausenderpunkt.
Darum bastelte ich an einer Lösung.

Der Grund warum ich das wissen wollte, ist folgender,denn jetz muß ich weiter
ausholen, was ich zuerst vermeiden wollte.
Ich hole CSV und Excel Bankdaten aus verschiedenen Banken um sie mittels Dataframe
in eine SQlite DB zu exportieren. War mit Excel kein Problem. Die andere Bank liefert
die CSV Daten in einer Soll und Haben Spalte, mit Komma und Tausenderpunkt.
mit pd.read_csv eingelesen mit apply(replace...) zuerst den Punkt entfernt,
danach das komma durch Punkt ersetzt und mit df['Haben']-df['Soll] eine Betragscolumne erstellt.
funktionierte alles gut, bis ich bemerkte, das replace bei einigen nicht funktioniert. (-34567 statt 234.67)
Diese Ziffer aus CSV kopiert und in Python mit type kontrolliert ergab tuple und das dürfte
der Grund für das Verhalten sein. Habe halt für 2020 in dem der Fehler auftrat die Spalte in Excel vorher umformatiert.

Es hat mich halt interessiert ob für Tupel to float eine ähnlich kurze Lösung wie die oben zitierte gibt.
Muss mir das Modul locale anschauen.
Ist jetzt leider etwas lang geworden, das wollte ich mir zuerst ersparen.

Gruß und Dank an alle.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ach du meine Güte. Wer auch immer diese Webseite verbrochen hat - ihm gehört der Internetführerschein entzogen.

Alles, was dieses Tupel zur Wandlung in ein float braucht, ist ein simples

f = t[0] * t[1] / 100

Das war es.
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

@Gerhardus: statt nachträglich irgendwie zuversichtlich, Daten zu reparieren ist, wie schon erwähnt, der falsche Weg. Wie es richtig geht, dazu müsste man wissen, wie die Dateien aussehen.

@__deets__: man muss halt wissen, was das Ergebnis von (3, 6) sein soll.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Sirius3: ich verstehe deinen Punkt nicht. Meinst du, dass die 6 in Wirklichkeit 60 sind? Das liesse sich ja auch trivial umsetzen, aber wäre auch schon sehr ungewöhnlich. Zumindest wenn ints sind. Da ist dann schon vorher Mist passiert.
Benutzeravatar
ThomasL
User
Beiträge: 1367
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Hi Gerhardus,
hast du dir denn schon mal die Möglichkeiten von pandas.read_csv() genau angeschaut?
https://pandas.pydata.org/docs/referenc ... d_csv.html

Ich könnte mir vorstellen, dass ein spielen mit den Parametern
engine : {‘c’, ‘python’, ‘pyarrow’}, optional
Parser engine to use. The C and pyarrow engines are faster, while the python engine is currently more feature-complete. Multithreading is currently only supported by the pyarrow engine.

converters : dict, optional
Dict of functions for converting values in certain columns. Keys can either be integers or column labels.

thousands : str, optional
Thousands separator.

decimal : str, default ‘.’
Character to recognize as decimal point (e.g. use ‘,’ for European data).
eventuell zum Erfolg führt.

Könntest du uns denn eventuell mal eine kleine csv Datei zur Verfügung stellen, in der ein paar Zeilen sind, die dieses Problem verursachen?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Gerhardus
User
Beiträge: 42
Registriert: Dienstag 31. Dezember 2013, 01:59

Hallo,
eigentlich wollte ich interessehalber vorerst nur wissen, ob es eine bessere Lösung als meine 'Bastellösung' gibt.

Code: Alles auswählen

t=(1.234,56)
f=t[0]*t[1]/100
schaut sehr einfach aus, funktioniert aber nur wenn kein Punkt vorkommt.

Werde mal die 2022 CSV Daten herunterladen, ob da auch solche inkonsequenten Daten vorkommen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was heisst denn da kommt ein Punkt vor? Das ist dann ja ein float Wert, und der ist eben 1.234. Was soll das denn heissen? Das es Eintausendzweihundervierundreissig sein sollen? Dann ist da etwas richtig schief gelaufen vorher. Denn so einen Wert darf man nie einfach zum float machen. Sondern muss das schon beim einlesen vernuenftig behandeln.
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

@Gerhardus: wie oft sollen wir das eigentlich noch schreiben: Deine "Bastellösung" ist gar keine Lösung, denn wenn Du die Zahlen beim Einlesen falsch in floats konvertierst, kann das hinterher niemand mehr reparieren. Du mußt die Daten schon beim Einlesen richtig behandeln.
Und ich bezweifle, dass die Bank "inkonseqeuente" Daten liefert, sondern dass DU sie einfach nur falsch interpretierst.
Gerhardus
User
Beiträge: 42
Registriert: Dienstag 31. Dezember 2013, 01:59

Hallo,

Sorry, für meinen 'Tupelwahn''. Ich hab nicht mitbekommen, das jede mit Komma getrennte Zahl von Python
ein Tupel ist, auch wenn sie nicht mit einer runden klammer erzeugt wird. Aber Dank eurer Hilfe habe ich das Problem gelöst.
Der wahre Fehler lag hauptsächlich darin, beide spalten mit replace zu bearbeiten, wobei dies nur bei der 'Haben' Spalte erforderlich war, in der
nur 0 oder Beträge mit Komma (jedoch rechtsbündig!) waren, im Gegensatz zur Sollspalte, wo panda alle Daten korrekt
eingelsen hat.
Nochmals Sorry und danke an alle Antworter.
Gruß
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich glaube, dein jetziger Ansatz ist immer noch nicht robust. Aber da Du Dich ja standhaft weigerst, die nötigen Informationen bereitzustellen, bleibt das Dein persönliches Risiko.
Gerhardus
User
Beiträge: 42
Registriert: Dienstag 31. Dezember 2013, 01:59

@sirius3:
Du hattest natürlich recht, kein replace mehr, das nicht 100% funktioniert .
Mit thousand="." in read_csv kommt Pandas mit den linksbündigen strings '1.234,56' zurecht. Eigentlich ganz einfach.
Sorry nochmals
Gerhardus
Antworten