如何将Pandas Series拆分为一个每天有小时的带有列的DataFrame?

时间:2019-04-22 12:47:00

标签: pandas pandas-groupby

我有一个Pandas系列太阳辐射值,其索引是带有一分钟分辨率的时间戳。例如:

index              solar_radiation
2019-01-01 08:01          0
2019-01-01 08:02         10
2019-01-01 08:03         15
...
2019-01-10 23:59          0

我想将其转换为一个表(DataFrame),其中每小时平均分为一列,例如:

index           00  01  02  03  04  05  06 ... 23
2019-01-01       0   0   0   0   0   3  10 ... 0
2019-01-02       0   0   0   0   0   4  12 ... 0
....
2019-01-10       0   0   0   0   0   6  24...  0

我试图研究Groupby,但是我只能将几个小时分组到一个合并的bin中,而不是每天分组一个……关于如何使用groupby实现此目的的任何提示或建议,还是我应该蛮力的,并在每个小时内进行迭代?

2 个答案:

答案 0 :(得分:3)

如果我对您的理解正确,则希望每小时使用resample。然后我们可以用MultiIndexdate制作一个hour,然后将hour的索引拆栈到列:

df = df.resample('H').mean()
df.set_index([df.index.date, df.index.time], inplace=True)
df = df.unstack(level=[1])

哪个提供给我们以下输出:

print(df)
           solar_radiation                                               \
                  00:00:00 01:00:00 02:00:00 03:00:00 04:00:00 05:00:00   
2019-01-01             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-02             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-03             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-04             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-05             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-06             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-07             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-08             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-09             NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-10             NaN      NaN      NaN      NaN      NaN      NaN   

                                                 ...                    \
           06:00:00 07:00:00  08:00:00 09:00:00  ... 14:00:00 15:00:00   
2019-01-01      NaN      NaN  8.333333      NaN  ...      NaN      NaN   
2019-01-02      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-03      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-04      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-05      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-06      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-07      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-08      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-09      NaN      NaN       NaN      NaN  ...      NaN      NaN   
2019-01-10      NaN      NaN       NaN      NaN  ...      NaN      NaN   

                                                                           \
           16:00:00 17:00:00 18:00:00 19:00:00 20:00:00 21:00:00 22:00:00   
2019-01-01      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-02      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-03      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-04      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-05      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-06      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-07      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-08      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-09      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-01-10      NaN      NaN      NaN      NaN      NaN      NaN      NaN   


           23:00:00  
2019-01-01      NaN  
2019-01-02      NaN  
2019-01-03      NaN  
2019-01-04      NaN  
2019-01-05      NaN  
2019-01-06      NaN  
2019-01-07      NaN  
2019-01-08      NaN  
2019-01-09      NaN  
2019-01-10      0.0  

[10 rows x 24 columns]

注意,因为您只提供了几行数据,所以我得到了很多NaN

答案 1 :(得分:1)

DataFrame列的解决方案:

通过meanregex汇总DatetimeIndexDatetimeIndex.floor,通过DatetimeIndex.hour进行整形并通过Series.unstack添加缺失值:< / p>

#if necessary
#df.index = pd.to_datetime(df.index)
rng = pd.date_range(df.index.min().floor('D'), df.index.max().floor('D'))
df1 = (df.groupby([df.index.floor('D'), df.index.hour])['solar_radiation']
         .mean()
         .unstack(fill_value=0)
         .reindex(columns=range(0, 24), fill_value=0, index=rng))

另一种按小时DataFrame.reindex的解决方案,将丢失的值替换为0,并用Grouper进行整形:

#if necessary
#df.index = pd.to_datetime(df.index)

df1 = df.groupby(pd.Grouper(freq='H'))[['solar_radiation']].mean().fillna(0)
df1 = df1.set_index([df1.index.date, df1.index.hour])['solar_radiation'].unstack(fill_value=0)
print (df1)
             0    1    2    3    4    5    6    7         8    9   ...   14  \
2019-01-01  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  8.333333  0.0  ...  0.0   
2019-01-02  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-03  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-04  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-05  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-06  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-07  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-08  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-09  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   
2019-01-10  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.000000  0.0  ...  0.0   

             15   16   17   18   19   20   21   22   23  
2019-01-01  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-02  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-03  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-04  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-05  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-06  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-07  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-08  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-09  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  
2019-01-10  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  

[10 rows x 24 columns]

Series with DatetimeIndex的解决方案:

rng = pd.date_range(df.index.min().floor('D'), df.index.max().floor('D'))
df1 = (df.groupby([df.index.floor('D'), df.index.hour])
         .mean()
         .unstack(fill_value=0)
         .reindex(columns=range(0, 24), fill_value=0, index=rng))

df1 = df.groupby(pd.Grouper(freq='H')).mean().to_frame('new').fillna(0)
df1 = df1.set_index([df1.index.date, df1.index.hour])['new'].unstack(fill_value=0)