2013-03-15 120 views
13

我从“。日期”列作为索引.csv文件读入以下数据帧。日子在行中,列显示当天小时的值。如何重新排列python熊猫数据框?

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

,我想这样的安排,所以有一个索引列的日期/时间和顺序

>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 

我用试图将其与值一列两个循环遍历数据帧。 有没有一个更简单的方法来做到这一点在熊猫?

回答

15

我不是最好的,在日期的操作,但也许是这样的:

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

一些解释如下。

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

开始,我们可以使用pd.melt,使每小时列合并到一列与价值:

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

摆脱那些h S的:

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

合并两列作为日期:

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

重新组装和清理:

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

不错的解决方案!你可以将'df ['hour']。apply(...)'和'combined = ...'行结合到'df ['Date'] + = df ['hour']。apply(lambda x: timedelta(小时= INT(x.lstrip( 'H')) - 1))'。 – unutbu 2013-03-15 13:28:06

+0

伟大的解决方案。非常感谢。我刚刚设置日期作为索引,它完美的作品。 > df = df.set_index('Date') – 2013-03-15 16:47:04

1

你总是可以抓住每小时data_array中和展平。您将使用小时频率生成新的DatetimeIndex。

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) 

我假设read_csv解析'日期'列并使其成为索引。我们更改为'D'的频率,以便new_ind正确排列,如果您缺少天数。缺失的日子将填写np.nan,你可以用s.dropna()加入。

notebook link