2013-03-15 7 views
13

Ich habe das folgende Datenformat aus einer CSV-Datei eingelesen, wobei die Spalte "Date" der Index ist. Die Tage sind in den Zeilen und die Spalten zeigen die Werte für die Stunden an diesem Tag.Wie man einen Python-Pandas-Datenrahmen neu anordnet?

> Date   h1 h2 h3 h4 ... h24 
> 14.03.2013 60 50 52 49 ... 73 

Ich mag würde es so arrangieren, so dass es ein Index Spalt mit dem Datum/Uhrzeit und eine Spalte mit den Werten in einer Sequenz

ist
>Date/Time   Value 
>14.03.2013 00:00:00 60 
>14.03.2013 01:00:00 50 
>14.03.2013 02:00:00 52 
>14.03.2013 03:00:00 49 
>. 
>. 
>. 
>14.03.2013 23:00:00 73 

ich es versuche, mit Hilfe zwei Schleifen, um den Datenrahmen zu durchlaufen. Gibt es einen einfacheren Weg, dies in Pandas zu tun?

Antwort

15

Ich bin nicht das beste zum Zeitpunkt Manipulationen, aber vielleicht etwas wie folgt aus:

import pandas as pd 
from datetime import timedelta 

df = pd.read_csv("hourmelt.csv", sep=r"\s+") 

df = pd.melt(df, id_vars=["Date"]) 
df = df.rename(columns={'variable': 'hour'}) 
df['hour'] = df['hour'].apply(lambda x: int(x.lstrip('h'))-1) 

combined = df.apply(lambda x: 
        pd.to_datetime(x['Date'], dayfirst=True) + 
        timedelta(hours=int(x['hour'])), axis=1) 

df['Date'] = combined 
del df['hour'] 

df = df.sort("Date") 

Eine Erklärung folgt.

von

Ab
>>> import pandas as pd 
>>> from datetime import datetime, timedelta 
>>> 
>>> df = pd.read_csv("hourmelt.csv", sep=r"\s+") 
>>> df 
     Date h1 h2 h3 h4 h24 
0 14.03.2013 60 50 52 49 73 
1 14.04.2013 5 6 7 8 9 

Wir pd.melt verwenden können, um die Stunde Spalten in eine Spalte mit diesem Wert zu machen:

>>> df = pd.melt(df, id_vars=["Date"]) 
>>> df = df.rename(columns={'variable': 'hour'}) 
>>> df 
     Date hour value 
0 14.03.2013 h1  60 
1 14.04.2013 h1  5 
2 14.03.2013 h2  50 
3 14.04.2013 h2  6 
4 14.03.2013 h3  52 
5 14.04.2013 h3  7 
6 14.03.2013 h4  49 
7 14.04.2013 h4  8 
8 14.03.2013 h24  73 
9 14.04.2013 h24  9 

Werden Sie jene h s los:

>>> df['hour'] = df['hour'].apply(lambda x: int(x.lstrip('h'))-1) 
>>> df 
     Date hour value 
0 14.03.2013  0  60 
1 14.04.2013  0  5 
2 14.03.2013  1  50 
3 14.04.2013  1  6 
4 14.03.2013  2  52 
5 14.04.2013  2  7 
6 14.03.2013  3  49 
7 14.04.2013  3  8 
8 14.03.2013 23  73 
9 14.04.2013 23  9 

Kombinieren Sie die beiden Spalten als Datum:

>>> combined = df.apply(lambda x: pd.to_datetime(x['Date'], dayfirst=True) + timedelta(hours=int(x['hour'])), axis=1) 
>>> combined 
0 2013-03-14 00:00:00 
1 2013-04-14 00:00:00 
2 2013-03-14 01:00:00 
3 2013-04-14 01:00:00 
4 2013-03-14 02:00:00 
5 2013-04-14 02:00:00 
6 2013-03-14 03:00:00 
7 2013-04-14 03:00:00 
8 2013-03-14 23:00:00 
9 2013-04-14 23:00:00 

wieder zusammenbauen und aufzuräumen:

>>> df['Date'] = combined 
>>> del df['hour'] 
>>> df = df.sort("Date") 
>>> df 
       Date value 
0 2013-03-14 00:00:00  60 
2 2013-03-14 01:00:00  50 
4 2013-03-14 02:00:00  52 
6 2013-03-14 03:00:00  49 
8 2013-03-14 23:00:00  73 
1 2013-04-14 00:00:00  5 
3 2013-04-14 01:00:00  6 
5 2013-04-14 02:00:00  7 
7 2013-04-14 03:00:00  8 
9 2013-04-14 23:00:00  9 
+0

Schöne Lösung! Sie könnten die 'df ['hour']. Apply (...)' und 'combined = ...' Zeilen in 'df ['Date'] + = df ['hour'] kombinieren. Apply (Lambda x: timedelta (Stunden = int (x.lstrip ('h')) - 1)) '. – unutbu

+0

Große Lösung. Danke vielmals. Ich habe gerade Date als Index eingestellt und es funktioniert perfekt. > df = df.set_index ('Datum') –

1

Sie können immer die stündlichen data_array greifen und es glätten. Sie würden einen neuen DatetimeIndex mit stündlicher Häufigkeit erzeugen.

Ich gehe davon aus, dass read_csv analysiert die 'Date' Spalte und macht es zum Index. Wir wechseln auf die Frequenz von "D", so dass die korrekt ausgerichtet ist, wenn Sie Tage fehlen. Die fehlenden Tage werden mit np.nan gefüllt, die Sie mit s.dropna() fallen lassen können.

notebook link