Hallo,
ich suche nach irgend einem Befehl, mit dem man
Dataframes zeilenweise bearbeiten kann,
sowas wie
from i=1 to len(dataframe) do
dataframe.firstcolumn=irgendwas
dataframe.secondcolumn=irgendwas
end
Scheinbar gibts diese Kontrollstruktur in Python aber gar nicht.
Mit for each Zeile in dataframe
passieren seltsame Sachen, der ganze Dataframe wird dann mehrmals durchgekämmt.
Wie muss kann so eine zeilenweise Bearbeitung machen?
Dataframe zeilenweise bearbeiten
@Stephan12: Was willst Du denn eigentlich machen? Eine ``for``-Schleife in Python über ein `numpy`-Array ist eigentlich immer nur die letzte Lösung wenn man es nicht mit Methoden und Funktion hinbekommt die `numpy` und `panda` bieten. Und eine ``for``-Schleife die über den Umweg eines Index auf fortlaufende Elemente einer Sequenz zugreifen ist in Python ein „anti pattern”.
``for each Zeile in dataframe`` ist keine gültige Python-Syntax weil es kein ``each``-Schlüsselwort gibt. Jede ``for``-Schleife in Python ist das was in anderen Sprachen ``for each``-Schleife heisst. Beim `dataframe` sind die Elemente über die man so iterieren kann aber nicht die Zeilen sondern die Namen der Spalten.
``for each Zeile in dataframe`` ist keine gültige Python-Syntax weil es kein ``each``-Schlüsselwort gibt. Jede ``for``-Schleife in Python ist das was in anderen Sprachen ``for each``-Schleife heisst. Beim `dataframe` sind die Elemente über die man so iterieren kann aber nicht die Zeilen sondern die Namen der Spalten.
Ich habe einen Dataframe, in dem in einer Spalte Datumsangaben stehen.
Diese will ich auf das Vorhandensein des dritten Samstags im Monat prüfen
und wenn das der Fall ist, diese Zeilen des gesamten Dataframes behalten, den Rest
verwerfen. Ich habe eine Funktion geschrieben, die für einen gegebenen Monat
und Jahr den 3. Samstag errechnet und mit dem Datumswert des
gerade abzuarbeitenden Elements in der Dataframespalte vergleicht.
Dann sollte jeweils true oder false rauskommen und aus diesen Werten entweder
eine neue Dataframespalte erzeugt oder gleich die betreffende Zeile
im Dataframe herausgefiltert werden. Ich hab das bisher mit den implementierten vektoriellen Pandasfunktionen
nicht hinbekommen und wollte es deshalb inkrementell lösen, also Zeile für Zeile in der Datumsspalte prüfen und Aktionen
in der betreffenden Dataframezeile durchführen.
Diese will ich auf das Vorhandensein des dritten Samstags im Monat prüfen
und wenn das der Fall ist, diese Zeilen des gesamten Dataframes behalten, den Rest
verwerfen. Ich habe eine Funktion geschrieben, die für einen gegebenen Monat
und Jahr den 3. Samstag errechnet und mit dem Datumswert des
gerade abzuarbeitenden Elements in der Dataframespalte vergleicht.
Dann sollte jeweils true oder false rauskommen und aus diesen Werten entweder
eine neue Dataframespalte erzeugt oder gleich die betreffende Zeile
im Dataframe herausgefiltert werden. Ich hab das bisher mit den implementierten vektoriellen Pandasfunktionen
nicht hinbekommen und wollte es deshalb inkrementell lösen, also Zeile für Zeile in der Datumsspalte prüfen und Aktionen
in der betreffenden Dataframezeile durchführen.
@Stephan12: Wenn Du eine Funktion hast die pro Datumswert Wahr/Falsch liefert, dann kannst Du die auf die Datumswerte mit der `map()`-Funktion anwenden und das resultierende Array als Index in den gesamten Datenframe verwenden. Mal an einem einfachen Beispiel mit einem Datenframe mit Zufallszahlen in den Spalten 'x' und 'y' und einer Spalte 'datum' in der ein ganzes Jahr an Daten stehen. Dass die Werte in dieser Spalte alle einmalig, regelmässig aufsteigend, und sortiert sind ist für den Vorgang nicht wichtig. War halt einfach die so zu generieren.
pd == pandas:

Code: Alles auswählen
In [154]: d
Out[154]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 365 entries, 0 to 364
Data columns (total 3 columns):
x 365 non-null values
y 365 non-null values
datum 365 non-null values
dtypes: datetime64[ns](1), float64(2)
In [155]: d.datum.map(pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset)
Out[155]:
0 False
1 False
2 False
3 False
4 False
5 False
6 False
7 False
8 False
9 False
10 False
11 False
12 False
13 False
14 False
...
350 False
351 False
352 False
353 False
354 False
355 False
356 False
357 False
358 False
359 False
360 True
361 False
362 False
363 False
364 False
Name: datum, Length: 365, dtype: bool
In [156]: d[d.datum.map(pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset)]
Out[156]:
x y datum
24 62.134000 65.927203 2014-01-25 00:00:00
52 80.218566 98.210317 2014-02-22 00:00:00
80 38.208752 96.189346 2014-03-22 00:00:00
115 82.704522 50.556027 2014-04-26 00:00:00
143 82.406230 40.177194 2014-05-24 00:00:00
178 38.855840 44.012386 2014-06-28 00:00:00
206 13.145839 60.348764 2014-07-26 00:00:00
234 50.999593 52.372542 2014-08-23 00:00:00
269 93.140144 48.018650 2014-09-27 00:00:00
297 45.916681 18.412948 2014-10-25 00:00:00
325 69.603523 26.544856 2014-11-22 00:00:00
360 69.541351 14.857823 2014-12-27 00:00:00
Wow, das funktioniert bei mir so, das hab ich allein mit einem ganzen Tag Probiererei nicht hinbekommen.
Allerdings hab ich Schwierigkeiten, die Syntax zu verstehen.
Wie kann man z.B. die Funktion pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset auf ein einzelnes
Pandas Datetime-Objekt anwenden? Ich hab das nicht hinbekommen. Ich hatte nicht mal eine Doku gefunden,
daß man .onOffset true ausgeben kann, wenn das WeekofMonth-Kriterium erfüllt ist.
Vorher hatte ich folgendes probiert:
filterframe=frame[frame.eins.isin(verfallstage)]
verfallstage war hierbei ein pandas.date_range
der filterframe war dann leer, obwohl etwas hätte drin stehen müssen. Evtl. wegen unterschiedlicher Datumsformate o.ä.
Zum Thema map(): Wie kann man hier eine Funktion implementieren, deren Inputs abhängig sind von den (unterschiedlichen)
Zahlen der Dataframezeilen?
z.B. Dataframe mit
'Spalte'
1 01.01.2010
2 02.01.2010
und der Funktion testfunktion(Spalte.month, Spalte.day)
Allerdings hab ich Schwierigkeiten, die Syntax zu verstehen.
Wie kann man z.B. die Funktion pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset auf ein einzelnes
Pandas Datetime-Objekt anwenden? Ich hab das nicht hinbekommen. Ich hatte nicht mal eine Doku gefunden,
daß man .onOffset true ausgeben kann, wenn das WeekofMonth-Kriterium erfüllt ist.
Vorher hatte ich folgendes probiert:
filterframe=frame[frame.eins.isin(verfallstage)]
verfallstage war hierbei ein pandas.date_range
der filterframe war dann leer, obwohl etwas hätte drin stehen müssen. Evtl. wegen unterschiedlicher Datumsformate o.ä.
Zum Thema map(): Wie kann man hier eine Funktion implementieren, deren Inputs abhängig sind von den (unterschiedlichen)
Zahlen der Dataframezeilen?
z.B. Dataframe mit
'Spalte'
1 01.01.2010
2 02.01.2010
und der Funktion testfunktion(Spalte.month, Spalte.day)
@Stephan12: Bei der Pandas-Dokumentation muss man wohl zwingend interaktiv die Objekte selbst inspizieren. Eine Erweiterte Python-Shell wie IPython oder bpython ist dabei recht nützlich. Auf `onOffset()` bin ich gekommen in dem ich mir live angeschaut hatte was diese Objekte so alles bieten. Sonst hätte ich mir nämlich mit den ”dokumentierten”¹ `rollback()` und `rollforward()` so etwas gebastelt.
Die `onOffset()`-Methode kann man auf ein einzelnes Objekt anwenden in dem man sie einfach aufruft und dabei das Objekt als Argument übergibt. Wenn man das mehrfach vorhat, beziehungsweise das in einem Programm verwendet welches man auch nach einem Jahr noch einfach verstehen möchte, sollte man die Methode vielleicht vorher an einen sprechenden Bezeichner binden, damit der Leser einfacher erfassen kann was da passiert:
Zur letzten Frage: Das geht gar nicht. Ich sehe aber auch nicht warum man das brauchen sollte, denn man kann den Wert aus der Spalte ja *in* der Funktion nach Monat und Tag fragen.
______
¹ Die Methoden werden im Fliesstext erwähnt sind aber nicht im Index zu finden.
Die `onOffset()`-Methode kann man auf ein einzelnes Objekt anwenden in dem man sie einfach aufruft und dabei das Objekt als Argument übergibt. Wenn man das mehrfach vorhat, beziehungsweise das in einem Programm verwendet welches man auch nach einem Jahr noch einfach verstehen möchte, sollte man die Methode vielleicht vorher an einen sprechenden Bezeichner binden, damit der Leser einfacher erfassen kann was da passiert:
Code: Alles auswählen
In [159]: t1, t2
Out[159]:
(Timestamp('2014-01-01 00:00:00', tz=None),
Timestamp('2014-12-27 00:00:00', tz=None))
In [160]: pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset(t1)
Out[160]: False
In [161]: pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset(t2)
Out[161]: True
In [162]: is_third_saturday_of_month = pd.datetools.WeekOfMonth(week=3, weekday=5).onOffset
In [163]: is_third_saturday_of_month(t1)
Out[163]: False
In [164]: is_third_saturday_of_month(t2)
Out[164]: True
______
¹ Die Methoden werden im Fliesstext erwähnt sind aber nicht im Index zu finden.
Ich hätte das gebraucht z.B. für den Fall, daß es nicht sowas wie WEEKOFMONTH.onoffset() gibt.BlackJack hat geschrieben:@Stephan12:
Zur letzten Frage: Das geht gar nicht. Ich sehe aber auch nicht warum man das brauchen sollte, denn man kann den Wert aus der Spalte ja *in* der Funktion nach Monat und Tag fragen.
Meine Funktion hätte dann als als Input Monat und Tag aus allen Datumswerten in der Datumsspalte
rausziehen und dann einen boolschen Wert berechnen müssen. Das hätte ich dann wohl irgendwie versucht,
mit map zu implementieren, um nicht über die ganze Spalte iterieren zu müssen.
Ich wüsste zwar, wie ich einen einzelnen Wert aus der Datumsspalte auswerte (mit Datumsspalte[Index])
aber wie das mit map() für alle Einträge funktioniert, wüsste ich nicht.
Mal noch ne ganz andere Pandas-Frage:
Ich will aus nem Dataframe nen Pivot-Table machen und auch die Daten im Index bei rows[] und colums[] im Pivot mit verwenden.
Wie geht das? Konnte ich auch nirgendwo finden.