2013-03-15 27 views
13

Aşağıdaki dataframe'i .csv dosyasından indeks olan "Date" sütunuyla okudum. Günler satırlarda ve sütunlar o saat için değerleri gösterir.Python pandaları veri çerçevesi nasıl yeniden düzenlenir?

> Date   h1 h2 h3 h4 ... h24 
> 14.03.2013 60 50 52 49 ... 73 
Ben tarih/saat ile bir indeks sütun ve ben kullanarak bu çalışıyordum bir dizi

>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 

değerlerle bir sütun olacak şekilde, bu şekilde düzenlemek istiyoruz

Dataframe'den geçmek için iki döngü. Pandalarda bunu yapmanın daha kolay bir yolu var mı?

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") 

Bazı açıklama aşağıdaki gibidir:

cevap

15

belki böyle bir şey tarih manipülasyonlara en iyisi değilim ama.

>>> 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 

bu h s kurtulun:

>>> 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 

Biz bu değerle tek sütuna saat sütunları yapmak için pd.melt kullanabilirsiniz

>>> 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 

başlayarak

İki sütunu bir tarih olarak birleştir:

>>> 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 

yeniden monte ve temizlemek:

>>> 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

Güzel çözüm! Df ['hour'] 'i birleştirebilirsin.Uygula (...) 've' kombine = ...' satırlarını df ['Date'] + = df ['hour'] içine alabilirsin.Uygula (lambda x: timedelta (saat = int (x.lstrip ('h')) - 1)) '. – unutbu

+0

Harika çözüm. Çok teşekkürler. Tarihi İndeks olarak ayarladım ve mükemmel çalışıyor. > df = df.set_index ('Tarih') –

1

Hep saatlik data_array kapmak ve onu dümdüz olabilir. Saatlik frek ile yeni bir DatetimeIndex oluşturur.

df = df.asfreq('D') 
hourly_data = df.values[:, :] 
new_ind = pd.date_range(start=df.index[0], freq="H", periods=len(df) * 24) 
# create Series. 
s = pd.Series(hourly_data.flatten(), index=new_ind) 

Şu anda read_csv'nin 'Tarih' sütununu ayrıştırdığını ve dizini oluşturduğunu varsayıyorum. Eksik günleriniz varsa, new_ind'un doğru şekilde hizalanabilmesi için 'D' sıklığına geçiyoruz. Eksik günler, s.dropna() ile bırakabileceğiniz np.nan ile doldurulacaktır.

notebook link

İlgili konular