Servus Forum,
es stellte sich mir die Frage wie ich in einem Pandas DataFrame einen Vergleich erstelle, der jeweils die drei aufeinanderfolgenden Zeilen einer Spalte miteinander vergleicht.
Ich habe hierzu in zahlreichen Internetseiten gelesen, dass man keine for Schleife, oder die iterrows Funktion verwenden
sollte, da diese sehr langsam sind.
Es sollte eher eine Vektorisierung angestrebt werden.
Wie würde soetwas umgesetzt werden?
Ich habe mich mit der Vektorisierung noch nie beschäftigt und habe auch noch keinen passenden Eintrag gefunden,
der mir eine gute Erklärung geliefert hat.
LG
Iteration über Pandas Dataframe
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
Es geht wie anstelle einer for Schleife dies in ein Vektorisierung umgesetzt wird
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
ich habe folgenden DataFrame
Jetzt möchte ich über den DataFrame iterieren und jeweils drei aufeinanderfolgende Jahre vergleichen, ob die Temperatur gestiegen ist.
Im Internet ist zu lesen, dass man die Funktion iterrows(), oder eine for Schleife nicht verwenden soll, da diese sehr langsam sind.
Bei 7 Zeilen ist dies zwar egal, aber was mache ich, wenn es sich um 7000, oder noch mehr Zeilen handelt?
LG
Code: Alles auswählen
import pandas as pd
jahrestemperatur = pd.DataFrame({"Datum": ["01.01.1900", "01.01.1910","01.01.1920","01.01.1930","01.01.1940","01.01.1950","01.01.1960"],
"Temperatur": [-12, -3, -25, -8, 0, 3, -16]})
Datum Temperatur
0 01.01.1900 -12
1 01.01.1910 -3
2 01.01.1920 -25
3 01.01.1930 -8
4 01.01.1940 0
5 01.01.1950 3
6 01.01.1960 -16
Im Internet ist zu lesen, dass man die Funktion iterrows(), oder eine for Schleife nicht verwenden soll, da diese sehr langsam sind.
Bei 7 Zeilen ist dies zwar egal, aber was mache ich, wenn es sich um 7000, oder noch mehr Zeilen handelt?
LG
- __blackjack__
- User
- Beiträge: 13928
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Hartmannsgruber: Also willst Du da mit einem Fenster drüber gehen? https://pandas.pydata.org/docs/user_guide/window.html
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Wenn Du zwei Temperaturen vergleichen willst, dann gibt es `diff`:
Wenn der Wert >0 ist, dann steigt die Temperatur, sonst fällt die Temperatur.
Wie sieht diese Operation bei drei Werten aus?
Code: Alles auswählen
jahrestemperatur['Temperatur'].diff()
Wie sieht diese Operation bei drei Werten aus?
- __blackjack__
- User
- Beiträge: 13928
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Als Ansatzpunkt:
Ausgabe:
Die ersten beiden sind `False` weil da das Ergebnis mit NaN vorbelegt ist, und ab da ist es immer `True` wenn die beiden vorhegehenden und der aktuelle Wert strikt monoton steigend sind, und `False` andernfalls.
Code: Alles auswählen
#!/usr/bin/env python3
import pandas as pd
def is_strictly_increasing(data):
return data.is_monotonic_increasing and data.is_unique
def main():
jahrestemperatur = pd.DataFrame(
{
"Datum": [
"01.01.1900",
"01.01.1910",
"01.01.1920",
"01.01.1930",
"01.01.1940",
"01.01.1950",
"01.01.1960",
],
"Temperatur": [-12, -3, -25, -8, 0, 3, -16],
}
)
print(jahrestemperatur.rolling(3).agg(is_strictly_increasing) > 0)
if __name__ == "__main__":
main()
Code: Alles auswählen
0 False
1 False
2 False
3 False
4 True
5 True
6 False
Name: Temperatur, dtype: bool
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
Mit den beiden Lösungen sollte das Problem gelöst sein.
Ich habe aber jetzt mal eine ganz andere Frage.
Woher wisst Ihr (__blackjack__, Sirius3) so viel über Python, (egal welches Gebiet, ob GUI, Allgemein, Datenbanken, oder jetzt Datenanalyse).
Macht Ihr dies Hauptberuflich, oder woher habt Ihr dieses umfangreich Wissen?
Allein die Pandas Bibliothek ist ja so umfangreich, woher weiß man da welche Funktionen es überhaupt gibt?
Ich habe aber jetzt mal eine ganz andere Frage.
Woher wisst Ihr (__blackjack__, Sirius3) so viel über Python, (egal welches Gebiet, ob GUI, Allgemein, Datenbanken, oder jetzt Datenanalyse).
Macht Ihr dies Hauptberuflich, oder woher habt Ihr dieses umfangreich Wissen?
Allein die Pandas Bibliothek ist ja so umfangreich, woher weiß man da welche Funktionen es überhaupt gibt?
- __blackjack__
- User
- Beiträge: 13928
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Hartmannsgruber: Ganz allgemein Erfahrung. Geboren wird man mit dem Wissen ja leider nicht.
Und dann ist das Stichwort was Sirius3 ja schon genannt hat: Stichworte. Das Konzept so eines Teilbereichs den man über eine Folge von Werten schiebt, heisst nicht nur bei Pandas „window“/„rolling window“ oder so ähnlich. Wo ich den Begriff das erste mal gehört habe, kann ich nicht sagen, aber ich kannte den vor Pandas schon, und auch schon bevor ich den in verschiedenen anderen Kontexten gesehen habe, beispielsweise Funktionen bei Datenbanken die unter der Überschrift „window functions“ in dokumentiert sind. Jedes mal wenn man das Konzept im Zusammenhang mit dem Begriff „window“ sieht, verankert sich das fester, dass man das als Stichwort parat hat, wenn man so etwas (wieder) braucht.
Und dann ist es naheliegend auch bei Bibliotheken die man noch nicht kennt, auch nach diesem Stichwort zu suchen, wenn man so eine Funktionalität sucht. Entweder in der Dokumentation der Bibliothek direkt, oder wenn man da nicht fündig wird, weil die das vielleicht anders nennen, im Netz nach „window functions for <bibliotheksname>“ zu suchen. Oder allgemein „<konzeptname> for <bibliotheksname>“. Das hilft oft auch wenn man den Namen eines ähnlichen Konzepts kennt.
Und dann ist es naheliegend auch bei Bibliotheken die man noch nicht kennt, auch nach diesem Stichwort zu suchen, wenn man so eine Funktionalität sucht. Entweder in der Dokumentation der Bibliothek direkt, oder wenn man da nicht fündig wird, weil die das vielleicht anders nennen, im Netz nach „window functions for <bibliotheksname>“ zu suchen. Oder allgemein „<konzeptname> for <bibliotheksname>“. Das hilft oft auch wenn man den Namen eines ähnlichen Konzepts kennt.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
Wenn man sich über die Jahre ein gutes "Stichwortverzeichnis" im Kopf zurechtlegt hat dies demnach enorme Vorteile im weiteren Umgang mit anderen Bibliotheken und co.
Der Erfahrungswert ist wohl hier wie auch in jeder anderen Branchen unschlagbar.
Eine letzte Frage hätte ich aber noch.
Das mit dem Fenstern habe ich mir gemerkt und auch schon nachgeschlagen.
Wie greift man aber auf einzelne Indexwerte eines solchen Fensters zu?
Mir scheint es so, als würde hier das Fenster immer nur im Ganzen bearbeitet werden.
Also in etwa so:
Der Erfahrungswert ist wohl hier wie auch in jeder anderen Branchen unschlagbar.
Eine letzte Frage hätte ich aber noch.
Das mit dem Fenstern habe ich mir gemerkt und auch schon nachgeschlagen.
Wie greift man aber auf einzelne Indexwerte eines solchen Fensters zu?
Mir scheint es so, als würde hier das Fenster immer nur im Ganzen bearbeitet werden.
Also in etwa so:
Code: Alles auswählen
jahrestemperatur.rolling(3)[0] < jahrestemperatur.rolling(3)[1] > jahrestemperatur.rolling(3)[2]
- __blackjack__
- User
- Beiträge: 13928
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Hartmannsgruber: `rolling()` ist noch kein Fenster, sondern ein Objekt das die Fenster ”liefert”. Zum Beispiel an eine Funktion die man wie in meinem Beispiel an die `agg()`-Methode übergibt. Die Funktion bekommt `DataFrame`-Objekte. Und der Rückgabewert landet dann als Ergebnis in einem `Series`-Objekt.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
Nehmen wir das genannte Beispiel.
Es wird nun eine Funktion in .agg aufgerufen.
In dieser Funktion soll nun auf die einzelnen Indizes zugreifen.
Es taucht dann der Fehler auf, dass [0] nicht gefunden wird was ja verständlich ist,
da nach dem ersten Aufruf der Index 0 nicht mehr dabei ist.
Es wird nun eine Funktion in .agg aufgerufen.
In dieser Funktion soll nun auf die einzelnen Indizes zugreifen.
Es taucht dann der Fehler auf, dass [0] nicht gefunden wird was ja verständlich ist,
da nach dem ersten Aufruf der Index 0 nicht mehr dabei ist.
Code: Alles auswählen
#!/usr/bin/env python3
import pandas as pd
def is_strictly_increasing(data):
#print(data[0])
#print(data[1])
#print(data[2])
if data[0] > data[1] < data[2]:
return True
#return data.is_monotonic_increasing and data.is_unique
def main():
jahrestemperatur = pd.DataFrame(
{
"Datum": [
"01.01.1900",
"01.01.1910",
"01.01.1920",
"01.01.1930",
"01.01.1940",
"01.01.1950",
"01.01.1960",
],
"Temperatur": [-12, -3, -25, -8, 0, 3, -16],
}
)
print(jahrestemperatur.rolling(3).agg(is_strictly_increasing) > 0)
if __name__ == "__main__":
main()
- __blackjack__
- User
- Beiträge: 13928
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Hartmannsgruber: Du kannst so schlicht und einfach nicht auf `DataFrame`\s zugreifen. Ein ``data[0]`` bedeutet, greife auf die Spalte mit dem Label 0 zu. So eine Spalte gibt es nicht. Es gibt da nur die Spalten "Datum" und "Temperatur". Du willst da ja wahrscheinlich in Spalte "Temperatur" auf die Zeilen mit dem `iloc`-Index 0, 1, und 2 zugreifen. Dann musst Du auch genau *das* machen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
-
- User
- Beiträge: 89
- Registriert: Mittwoch 15. Januar 2014, 22:30
- Wohnort: Bad Kötzting
- Kontaktdaten:
Wenn ich die Funktion wie oben aufrufe erhalte ich folgende Ausgabe:
Wenn ich versuche nun während des Funktionsaufrus darauf zu zu greifen, erhalte ich immer die selben Fehler:
bitte um Erklärung wie das gehen soll....
Wenn das eine größere Baustelle ist/wird, wie schafft man es mit einer for Schleife in Python schnell über eine Liste mit 20.000 Einträgen zu iterieren?
Dann werfe ich einfach das pandas raus und gut ists.
Code: Alles auswählen
0 -12.0
1 -3.0
2 -25.0
dtype: float64
1 -3.0
2 -25.0
3 -8.0
dtype: float64
2 -25.0
3 -8.0
4 0.0
dtype: float64
3 -8.0
4 0.0
5 3.0
dtype: float64
4 0.0
5 3.0
6 -16.0
dtype: float64
Code: Alles auswählen
print(data[0]) # -> KeyError: 0
print(data["Temperatur"][0] # -> KeyError: 'Temperatur'
print(data[0]["Temperatur"] # -> IndexError: invalid index to scalar variable.
print(data.iloc(0))
print(data.iloc(1)) # -> ValueError: No axis named 1 for object type <class 'pandas.core.series.Series'>
print(data["Temperatur"].iloc(0)) # -> KeyError: 'Temperatur'
print(data.iloc(0)["Temperatur"]) # -> TypeError: Cannot index by location index with a non-integer key
Wenn das eine größere Baustelle ist/wird, wie schafft man es mit einer for Schleife in Python schnell über eine Liste mit 20.000 Einträgen zu iterieren?
Dann werfe ich einfach das pandas raus und gut ists.
-
- User
- Beiträge: 510
- Registriert: Mittwoch 13. November 2019, 08:38
Verstehe ich das Problem nicht oder suchst du einfach nur die korrekte Verwendung von iloc?
Code: Alles auswählen
# einzubinden in den vorherigen Beispielcode:
# ...
def is_strictly_increasing(data):
print(data.iloc[0])
return data.is_monotonic_increasing and data.is_unique
# ...