it-swarm.com.de

Datenrahmenserien eines Pandas nach Monatsnamen sortieren?

Ich habe ein Serienobjekt mit:

    date   price
    dec      12
    may      15
    apr      13
    ..

Problemstellung: Ich möchte es monatlich erscheinen lassen und den Durchschnittspreis für jeden Monat berechnen und es nach Monaten sortiert darstellen.

Gewünschte Ausgabe:

 month mean_price
  Jan    XXX
  Feb    XXX
  Mar    XXX

Ich dachte daran, eine Liste zu erstellen und sie in einer Sortierfunktion zu übergeben:

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

aber das sort_values ​​unterstützt das für Serien nicht.

Ein großes Problem, das ich habe, ist das, obwohl

df = df.sort_values(by='date',ascending=True,inplace=True) arbeitet mit der anfänglichen df, aber nachdem ich eine groupby erstellt habe, wurde die Reihenfolge, die aus der sortierten df hervorgeht, nicht beibehalten.

Abschließend benötigte ich aus dem anfänglichen Datenrahmen diese beiden Spalten. Sortierte die datetime-Spalte und durch eine Gruppe nach dem Monat (dt.strftime ('% B')) wurde die Sortierung durcheinander gebracht. Jetzt muss ich es nach Monatsnamen sortieren.


Mein Code:

df # has 5 columns though I need the column 'date' and 'price'

df.sort_values(by='date',inplace=True) #at this part it is sorted according to date, great
total=(df.groupby(df['date'].dt.strftime('%B'))['price'].mean()) # Though now it is not as it was but instead the months appear alphabetically
5
J_p

Danke, @Brad Solomon, dass Sie eine schnellere Methode zur Aktivierung von Zeichenketten anbieten!

Anmerkung 1 @Brad Solomons Antwort mit pd.categorical sollte Ihre Ressourcen mehr sparen als meine Antwort. Er zeigte, wie Sie Ihren kategorialen Daten eine Reihenfolge zuweisen. Sie sollten es nicht verpassen: P

Alternativ können Sie verwenden.

df = pd.DataFrame([["dec", 12], ["jan", 40], ["mar", 11], ["aug", 21],
                  ["aug", 11], ["jan", 11], ["jan", 1]], 
                   columns=["Month", "Price"])
# Preprocessing: capitalize `jan`, `dec` to `Jan` and `Dec`
df["Month"] = df["Month"].str.capitalize()

# Now the dataset should look like
#   Month Price
#   -----------
#    Dec    XX
#    Jan    XX
#    Apr    XX

# make it a datetime so that we can sort it: 
# use %b because the data use the abbriviation of month
df["Month"] = pd.to_datetime(df.Month, format='%b', errors='coerce').dt.month
df = df.sort_values(by="Month")

total = (df.groupby(df['Month"])['Price'].mean())

# total 
Month
1     17.333333
3     11.000000
8     16.000000
12    12.000000

Hinweis 2 groupby sortiert Gruppenschlüssel für Sie. Seien Sie sich bewusst, dass Sie den gleichen Schlüssel zum Sortieren und Gruppieren in df = df.sort_values(by=SAME_KEY) und total = (df.groupby(df[SAME_KEY])['Price'].mean()). verwenden. Andernfalls kann es zu unbeabsichtigtem Verhalten kommen. Siehe Gruppenzugehörigkeit zwischen Gruppen bewahren? Auf welche Weise? für mehr Informationen.

Anmerkung 3 Eine rechnerisch effizientere Methode ist, zuerst den Mittelwert zu berechnen und dann nach Monaten zu sortieren. Auf diese Weise müssen Sie nur 12 Elemente sortieren und nicht die gesamte df. Es reduziert den Rechenaufwand, wenn df nicht sortiert werden muss.

Anmerkung 4 Für Leute, die bereitsmonth als Index haben, und sich fragen, wie man sie kategorialisieren kann, werfen Sie einen Blick auf pandas .CategoricalIndex @jezrael hat ein funktionierendes Beispiel für die Kategorisierung Index sortiert in Pandas-Serie nach Monat sortieren Index

2
Tai

Sie können kategoriale Daten verwenden, um eine korrekte Sortierung zu ermöglichen:

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", 
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
df['months'] = pd.Categorical(df['months'], categories=months, ordered=True)
df.sort_values(...)  # same as you have now; can use inplace=True

Wenn Sie die Kategorien angeben, speichert Pandas die Sortierreihenfolge als Standardsortierreihenfolge.

Dokumente: Pandas Kategorien> Sortierung & Reihenfolge .

6
Brad Solomon

Ich würde das calender Modul und reindex benutzen:

series.str.capitalize hilft bei der Großschreibung der Reihe, dann erstellen wir ein Wörterbuch mit dem Modul calender und map mit der Reihe bis Monatszahl abrufen.

Sobald wir die Monatszahl haben, können wir sort_values() und den Index erhalten. Dann reindex .

import calendar
df.date=df.date.str.capitalize() #capitalizes the series
d={i:e for e,i in enumerate(calendar.month_abbr)} #creates a dictionary
#d={i[:3]:e for e,i in enumerate(calendar.month_name)} 
df.reindex(df.date.map(d).sort_values().index) #map + sort_values + reindex with index

  date  price
2  Apr     13
1  May     15
0  Dec     12
1
anky_91

Sie sollten in Betracht ziehen, es basierend auf Achse 0 (Indizes) neu zu indizieren.

new_order = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

df1 = df.reindex(new_order, axis=0)
0
Abhay S

verwenden Sie die Funktion Sort_Dataframeby_Month , um die Monatsnamen in chronologischer Reihenfolge zu sortieren

Pakete müssen installiert werden.

$ pip install sorted-months-weekdays
$ pip install sort-dataframeby-monthorweek

beispiel:

from sorted_months_weekdays import *

from sort_dataframeby_monthorweek import *

df = pd.DataFrame([['Jan',23],['Jan',16],['Dec',35],['Apr',79],['Mar',53],['Mar',12],['Feb',3]], columns=['Month','Sum'])
df
Out[11]: 
  Month  Sum
0   Jan   23
1   Jan   16
2   Dec   35
3   Apr   79
4   Mar   53
5   Mar   12
6   Feb    3

Um den Datenrahmen nach Monat zu sortieren, verwenden Sie die unten stehende Funktion

Sort_Dataframeby_Month(df=df,monthcolumnname='Month')
Out[14]: 
  Month  Sum
0   Jan   23
1   Jan   16
2   Feb    3
3   Mar   53
4   Mar   12
5   Apr   79
6   Dec   35
0
Dinesh Babu

Sie können den numerischen Monatswert zusammen mit dem Namen im Index (d. H. "01. Januar") hinzufügen, sortieren und dann die Nummer entfernen:

total=(df.groupby(df['date'].dt.strftime('%m %B'))['price'].mean()).sort_index()

Es könnte so aussehen:

01 January  xxx
02 February     yyy
03 March    zzz
04 April    ttt

 total.index = [ x.split()[1] for x in total.index ]

January xxx
February yyy
March zzz
April ttt
0
Zellint