2017-12-25 5 views
1

Ich habe eine Serie mit 305 Einträge, die mit Datatime-Index. die Daten wie folgt aussiehtReshape Series in Dataframe Matrix in Python

1992-01-31  1.123077 
1992-02-28 -2.174845 
1992-03-31 -3.884848 
1992-04-30  8.682919 
1992-05-29  1.312976 
1992-06-30  7.851080 
1992-07-31 -3.192788 
1992-08-31 -7.351976 
1992-09-30 -6.782217 
1992-10-30 -17.182738 
1992-11-30  3.898782 
1992-12-31 -26.190414 
1993-01-29  2.233359 
1993-02-26  6.709006 
continues with monthly data till December 2017 

Ich möchte die Daten als Datenrahmen neu zu gestalten, die alle Jahre für Zeilen und Monate für Spalten und Daten entsprechend

 January February March  etc >> December 
2017 values values values values values 
2016 values values values values values 
2015 values values values values values 
etc \\// 
1992 values     

ich an anderen Stellen sah zu füllen hat und versucht, Reshape und Asmatrix, aber da es eine unebene Serie ist, bekomme ich diesen Fehler.

ValueError: Die Gesamtgröße des neuen Arrays muss unverändert bleiben.

Was ich wirklich tun möchte, ist, wenn die Matrix ungerade ist, dann NaN für die fehlenden Werte einfügen. Also, wenn es keine November oder Dezember Werte im Jahr 2017 war sie würden NaN

sein lassen Sie mich wissen, ob jemand

Antwort

2

Quelle DF helfen:

In [159]: df 
Out[159]: 
        val 
date 
1992-01-31 1.123077 
1992-02-28 -2.174845 
1992-03-31 -3.884848 
1992-04-30 8.682919 
1992-05-29 1.312976 
1992-06-30 7.851080 
1992-07-31 -3.192788 
1992-08-31 -7.351976 
1992-09-30 -6.782217 
1992-10-30 -17.182738 
1992-11-30 3.898782 
1992-12-31 -26.190414 
1993-01-29 2.233359 
1993-02-26 6.709006 

Lösung:

import calendar 

In [158]: (df.assign(year=df.index.year, mon=df.index.month) 
      .pivot(index='year', columns='mon', values='val') 
      .rename(columns=dict(zip(range(13), calendar.month_name)))) 
Out[158]: 
mon January February  March  April  May  June  July August September October November December 
year 
1992 1.123077 -2.174845 -3.884848 8.682919 1.312976 7.85108 -3.192788 -7.351976 -6.782217 -17.182738 3.898782 -26.190414 
1993 2.233359 6.709006  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN 

UPDATE: oder viel schöner und kürzer version from @COLDSPEED:

In [164]: pd.pivot(df.index.year, df.index.month, df['val']) \ 
      .rename(columns=calendar.month_name.__getitem__) 
Out[164]: 
date January February  March  April  May  June  July August September October November December 
date 
1992 1.123077 -2.174845 -3.884848 8.682919 1.312976 7.85108 -3.192788 -7.351976 -6.782217 -17.182738 3.898782 -26.190414 
1993 2.233359 6.709006  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN 
+0

ich diese Idee im Sinn hatte, endete für ein paar Minuten trat weg und Sie haben es schon geschrieben! Soll ich löschen? –

+1

@ cᴏʟᴅsᴘᴇᴇᴅ, nein, bitte lösche es nicht - es ist anders – MaxU

+2

Prost, schätze es! –

0

Probieren Sie etwas wie

#Give your series index a name so that we can reset index and have a new column 
your_series.index = your_series.index.rename('Time') 
df = your_series.toframe('Values').reset_index() 

#Create variables for month and year 
df['Month'] = df.Time.dt.month 
df['Year'] = df.Time.dt.Year 

#Assuming they are unique, create a pivot table 
df.pivot('Year','Month','Values') 

Die Monate werden numerisch sein. Wenn Sie die Namen des Monats möchten, müssen Sie

import datetime as dt 

df['Month'] = df.Time.date.apply(lambda x: dt.datetime.strftime(x,'%B')) 

Wenn Ihr Monat/Jahr-Paare sind nicht eindeutig zu tun haben, dann tun Sie etwas wie

df.groupby(['Year','Month']).Values.sum().unstack() 
+0

@MaxU >> Das sieht nach der besten Lösung aus, aber als ich es ausprobiert habe, bekomme ich KeyError: 'val'. Müssen Sie die Werte zuweisen? jede Hilfe damit oder ich mache etwas falsch/etwas fehlt –

+0

@MaxU. Sorry, ich habe gerade verstanden, dass das der Spaltentitel in DF war. Es klappt. –

+0

@JWestwood Wenn die Antwort von MaxU hilfreich war, markieren Sie diese bitte durch Klicken auf das graue Häkchen neben der Antwort.Sie haben übrigens auf die falsche Antwort geantwortet. –

2
s 

1992-01-31  1.123077 
1992-02-28 -2.174845 
1992-03-31 -3.884848 
1992-04-30  8.682919 
1992-05-29  1.312976 
1992-06-30  7.851080 
1992-07-31 -3.192788 
1992-08-31 -7.351976 
1992-09-30 -6.782217 
1992-10-30 -17.182738 
1992-11-30  3.898782 
1992-12-31 -26.190414 
1993-01-29  2.233359 
1993-02-26  6.709006 
Name: 1, dtype: float64 

type(s) 
pandas.core.series.Series 

Falls notwendig, wandeln die Index datetime -

s.index = pd.to_datetime(s.index, errors='coerce') 

, verwenden nun pd.pivot -

x = pd.Series(s.index.strftime('%Y %B')).str.split() 
y, m = x.str[0], x.str[1] 

pd.pivot(y, m, s) 

     April August December February January  July  June \ 
1992 8.682919 -7.351976 -26.190414 -2.174845 1.123077 -3.192788 7.85108 
1993  NaN  NaN  NaN 6.709006 2.233359  NaN  NaN 

     March  May November October September 
1992 -3.884848 1.312976 3.898782 -17.182738 -6.782217 
1993  NaN  NaN  NaN  NaN  NaN