for-loop mit forex-python

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Voluntarist
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 20:31

Ich bin Pythonanfänger und neu hier im Forum, also entschuldige ich mich schon mal, falls ich dies am falschen Ort gepostet habe, oder die Frage unverständlich formuliert habe. Ich habe eine dataframe mit einer Spalte die Daten und Uhrzeit erhält und will für diese mithilfe des forex-python Modul für jede Zeile eine entsprechen Currency Exchangrate bekommen. Die Daten sind im folgenden Format als Str gespeichert.

0 2013-10-01 00:00:26
2 2013-10-01 00:01:28
4 2013-10-01 00:01:29
6 2013-10-01 00:01:29
8 2013-10-01 00:01:29
10 2013-10-01 00:01:29
...

Code: Alles auswählen

import pandas as pd
import numpy as np
from datetime import datetime
from forex_python.converter import get_rate
from forex_python.converter import CurrencyRates
c = CurrencyRates()
DateList = df['Date'].tolist() #um eine Liste zu bekommen

c.get_rate('USD', 'JPY', datetime.datetime.strptime(DateList[1], "%Y-%m-%d %H:%M:%S")) # So bekomme ich die rate für einen einzelnen Wert der Liste. Dann sollte es doch auch als for loop gehen?
rates = []
for x in DateList:
    c.get_rate('USD', 'JPY', datetime.datetime.strptime(x, "%Y-%m-%d %H:%M:%S"))
    rates.append(c.get_rate('USD', 'JPY', datetime.datetime.strptime(i, "%Y-%m-%d %H:%M:%S"))
Der for Loop funktioniert jedoch nicht und ich verstehe nicht warum. Danke für eure Hilfe!
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Voluntarist: „funktionier nicht“ ist eine schlechte Fehlerbeschreibung. Was passiert exakt? Gibt es eine Fehlermeldung? `c`, `x` und `i` sind schlechte Variablennamen, weil sie nichts aussagen, `i` ist zudem nicht definiert. `DateList` sollte komplett klein geschrieben werden, und besser `dates` heißen, weil Typinformation nichts in einem Variablennamen zu suchen haben.
Voluntarist
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 20:31

@Sirius3

Danke für dein Feedback! Das mit den Bezeichnungen macht Sinn und den Fehler hätte ich natürlich auch mitliefern können. Ich habe den code dementsprechend angepasst.

Code: Alles auswählen

import pandas as pd
import numpy as np
from datetime import datetime
from forex_python.converter import get_rate
from forex_python.converter import CurrencyRates
currencyrates = CurrencyRates()
alledaten = df['Date'].tolist() #um eine Liste zu bekommen #was meinst du zu "alledaten"? Ist das eine praktikable Bezeichnung?

#alledaten ist eine Liste mit string Objekten. Die kann man mit folgendem loop in eine datetime.dateime Liste konvertieren:

alledaten_in_anderem_format = []
for daten2013 in alledaten: #daten2013 sind die einzelnen string Objekte der Liste alledaten
    datetime.datetime.strptime(daten2013, "%Y-%m-%d %H:%M:%S") #so lassen sich die String in datetime.dateime Objekte konvertieren
    alledaten_in_anderem_format.append(datetime.datetime.strptime(daten2013, "%Y-%m-%d %H:%M:%S")) #alledaten_in_anderem_format --> Liste mit datetime.datetime Objekten
 
currencyrates.get_rate('USD', 'JPY', alledaten_in_anderem_format[1])# So bekomme ich die rate für einen einzelnen (hier den ersten) Wert der Liste alledaten_in_anderem_format. Dann sollte es doch auch als for loop gehen?

rates = []
for datum_anderes_format in alledaten_in_anderem_format: # "datum_anderes_format" für die Objekte der Liste alledaten_in_anderem_format
    currencyrates.get_rate('USD', 'JPY', (datum_anderes_format))
    rates.append(currencyrates.get_rate('USD', 'JPY', datum_anderes_format))
Es gibt mir folgende Fehlermeldung:
RatesNotAvailableError Traceback (most recent call last)
<ipython-input-198-3dcde99986a6> in <module>()
1 rates = []
2 for datum_in_anderem_format in alledaten_in_anderem_format:
----> 3 currencyrates.get_rate('USD', 'JPY', datum_in_anderem_format)
4 rates.append(currencyrates.get_rate('USD', 'JPY', datum_in_anderem_format))

C:\ProgramData\Anaconda3\lib\site-packages\forex_python\converter.py in get_rate(self, base_cur, dest_cur, date_obj)
67 base_cur, dest_cur, date_str))
68 return rate
---> 69 raise RatesNotAvailableError("Currency Rates Source Not Ready")
70
71 def convert(self, base_cur, dest_cur, amount, date_obj=None):

RatesNotAvailableError: Currency Rates Source Not Ready

Als date_obj gibt es date_obj=None an und Currency Rates Source Not Ready laut Fehlermeldung. Für einzelne Objekte der Liste hat es geklappt, aber da die Liste tausende Objekte enthält wäre eine loop der alle durchgeht ideal.
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Fehlermeldung »Currency Rates Source Not Ready« sagt leider nicht, was der wirkliche Fehler ist. Mit welchem Datum rufst Du »get_rate« auf?
Voluntarist
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 20:31

Ich bin mir nicht sicher, ob ich die Frage richtig verstanden habe, aber für ein einzelnes Datum kann ich mit einem datetime.datetime Objekt der Liste alle_daten_in_anderem Format abrufen. Das Beispiel :


Code: Alles auswählen


In[191]:
alledaten_in_anderem_format[1]

Out[191]:
datetime.datetime(2013, 10, 1, 0, 1, 28) 

#get_rate braucht das datetime.datetime Format, darum habe ich die Liste konvertiert in datetime.datetime konvertiert. Mit einem einzelnen Element klappt es auch:

In[197]:
currencyrates.get_rate('USD', 'JPY', alledaten_in_anderem_format[1])

Out[197]:
97.831

#Die rates sollen jedoch nicht nur für ein einzlenes Datum von alledaten_in_anderem_format, sondern für alle Elemente der Liste berechnet werden. In folgender Schlaufe sollten also für alle Elemente (datetime.datetime Objekte ) die rates berechnet werden:

rates = []
for datum_in_anderem_format in alledaten_in_anderem_format:
    currencyrates.get_rate('USD', 'JPY', datum_in_anderem_format)
    rates.append(currencyrates.get_rate('USD', 'JPY', datum_in_anderem_format))

Ich verstehe die basics von Schleifen, aber mein Verständnis reicht ehrlich gesagt nicht aus um hier den Fehler zu finden. Tutorials zu Schleifen haben mir nicht weitergeholfen.
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Voluntarist: eines von Deine vielen Datums in der Liste funktioniert nicht, da wäre es doch gut zu wissen, welches.
Voluntarist
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 20:31

@Sirius3

Die Liste enthält eben über 500000 Einträge und ich habe noch duzende gleiche Listen, also Millionen von Elementen die ich nie alle manuell durchgehen kann. Scheitert der Loop bereits, wenn nur ein Element nicht stimmt bzw. gibt es eine Möglichkeit effizient herauszufinden, an welchem Element es scheitert und dieses zu entfernen?

[EDIT]

PS: Ich habe den Loop mal für einen kleinen Teil der Liste [1:10] ausprobiert, das klappt manchmal und gibt die gewünschte Liste raus, aber leider auch nicht immer. Wie kann es sein, dass der Befehl manchmal klappt, und dann wieder nicht? Kann es daran liegen, dass mein Rechner zu wenig Leistung/RAM hat?
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

dann liegt es wohl daran, dass der Dienst, den Du da benutzt, nicht mit Deinen Denial-of-Service-Attacken zurechkommt. Wohl zu recht. Da ist es besser, die Zeitreihen direkt von der Quelle herunterzuladen: https://www.ecb.europa.eu/stats/policy_ ... ex.en.html
Voluntarist
User
Beiträge: 5
Registriert: Dienstag 12. Dezember 2017, 20:31

Okay, danke. Kann man python nicht sagen, dass es die Abfragen langsamer angehen soll um den Server nicht zu überlasten?

Ich habe mich auf der Seite umgesehen, aber finde die Quelle ehrlich gesagt nicht. Ich glaube, dass das Modul den Umrechnner auf dieser Seite (http://sdw.ecb.europa.eu/curConverter.d ... onvert.y=6) als Quelle nimmt, welche wiederum die Rates von Bloomberg hat.

Ich muss es wohl auf einem alternativen Weg machen. Ich habe sogar die rates in meinem Datensatz, aber das Problem ist, dass dazwischen rates sind die ich nicht brauchen kann, weil die in einer anderen Währung sind.

Kannst du mir ein gutes Tutorial empfehlen? Diejenigen die ich jeweils gefunden habe sind meistens entweder zu basic oder dann wieder zu komplex für das was ich machen will.
Antworten