gruppieren Sie nach Pandas Datenrahmen und wählen Sie spätestens in jeder Gruppe

74

Wie gruppiere ich die Werte des Pandas-Datenrahmens und wähle aus jeder Gruppe die neuesten (nach Datum) aus?

Beispiel: Ein Datenrahmen ist nach Datum sortiert:

    id     product   date
0   220    6647     2014-09-01 
1   220    6647     2014-09-03 
2   220    6647     2014-10-16
3   826    3380     2014-11-11
4   826    3380     2014-12-09
5   826    3380     2015-05-19
6   901    4555     2014-09-01
7   901    4555     2014-10-05
8   901    4555     2014-11-01

Gruppierung nach ID oder Produkt und Auswahl der frühesten ergibt:

    id     product   date
2   220    6647     2014-10-16
5   826    3380     2015-05-19
8   901    4555     2014-11-01
DevEx
quelle

Antworten:

53

Verwendung idxmaxin groupbyund in Scheiben schneiden dfmitloc

df.loc[df.groupby('id').date.idxmax()]

    id  product       date
2  220     6647 2014-10-16
5  826     3380 2015-05-19
8  901     4555 2014-11-01
piRSquared
quelle
2
Die Lösung funktioniert für Millionen von Datensätzen sehr langsam
Hardik Gupta
84

Sie können auch tailmit groupby verwenden, um die letzten n Werte der Gruppe abzurufen:

df.sort_values('date').groupby('id').tail(1)

    id  product date
2   220 6647    2014-10-16
8   901 4555    2014-11-01
5   826 3380    2015-05-19
ade1e
quelle
4
Ich mag das, weil es auf mehr als nur Daten angewendet werden kann.
Scottlittle
Diese Option ist erheblich schneller als die akzeptierte Antwort, jedoch weniger lesbar. Ist es auch nicht problematisch, dass es eine Annahme gibt, groupbydie Ordnung bewahrt?
Michael D
1
groupby behält Ordnung bei, siehe stackoverflow.com/questions/26456125/…
Martien Lubberink
@ ade1e Wie würde sich der Code ändern, um ein Resample durchzuführen (z. B. pro Monat oder Jahr) und die letzten n Werte der Gruppe beizubehalten, anstatt zu summieren / zu mitteln?
Andreuccio
14

Ich hatte ein ähnliches Problem und benutzte es drop_duplicateseher als groupby.

Es scheint bei großen Datenmengen im Vergleich zu anderen oben vorgeschlagenen Methoden signifikant schneller zu laufen.

df.sort_values(by="date").drop_duplicates(subset=["id"], keep="last")

    id  product        date
2  220     6647  2014-10-16
8  901     4555  2014-11-01
5  826     3380  2015-05-19
Damien Marlier
quelle
Normalerweise benutze ich das auch, aber ich wünschte, die schnellere Lösung wäre mit dem Groupby. Die Gruppierung macht intuitiv mehr Sinn und ist normalerweise die Art und Weise, wie wir über die Lösung dieses Problems nachdenken!
Milletich
11

Bei einem nach Datum sortierten Datenrahmen können Sie auf verschiedene Arten das erhalten, wonach Sie fragen:

So was:

df.groupby(['id','product']).last()

so was:

df.groupby(['id','product']).nth(-1)

oder so:

df.groupby(['id','product']).max()

Wenn Sie nicht möchten idund productals Index angezeigt werden sollen, verwenden Sie groupby(['id', 'product'], as_index=False). Alternativ verwenden Sie:

df.groupby(['id','product']).tail(1)
Sandu Ursu
quelle
1

So verwenden Sie es .tail()als Aggregationsmethode und behalten Ihre Gruppierung bei:

df.sort_values('date').groupby('id').apply(lambda x: x.tail(1))

        id  product date
id              
220 2   220 6647    2014-10-16
826 5   826 3380    2015-05-19
901 8   901 4555    2014-11-01
Kristin Q.
quelle