2012-04-04 61 views
21

我有一個熊貓溫度和輻射時間系列dataframe。時間分辨率是常規步驟中的1分鐘。如何重新採樣應用於每列的不同函數的數據幀?

import datetime 
import pandas as pd 
import numpy as np 

date_times = pd.date_range(datetime.datetime(2012, 4, 5, 8, 0), 
          datetime.datetime(2012, 4, 5, 12, 0), 
          freq='1min') 
tamb = np.random.sample(date_times.size) * 10.0 
radiation = np.random.sample(date_times.size) * 10.0 
frame = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation}, 
        index=date_times) 
frame 
<class 'pandas.core.frame.DataFrame'> 
DatetimeIndex: 241 entries, 2012-04-05 08:00:00 to 2012-04-05 12:00:00 
Freq: T 
Data columns: 
radiation 241 non-null values 
tamb   241 non-null values 
dtypes: float64(2) 

我怎麼能下采樣這一dataframe一小時的分辨率,計算每小時意味着的溫度和輻射每小時總和

回答

41

隨着熊貓0.18重新採樣API的變化(見docs)。 所以對於熊貓> = 0.18答案是:

In [31]: frame.resample('1H').agg({'radiation': np.sum, 'tamb': np.mean}) 
Out[31]: 
         tamb radiation 
2012-04-05 08:00:00 5.161235 279.507182 
2012-04-05 09:00:00 4.968145 290.941073 
2012-04-05 10:00:00 4.478531 317.678285 
2012-04-05 11:00:00 4.706206 335.258633 
2012-04-05 12:00:00 2.457873 8.655838 

老答案:

我回答我的問題,以反映pandas >= 0.8時間序列相關的變化(所有其他的答案是過時的)。

使用熊貓> = 0.8的答案是:

In [30]: frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean}) 
Out[30]: 
         tamb radiation 
2012-04-05 08:00:00 5.161235 279.507182 
2012-04-05 09:00:00 4.968145 290.941073 
2012-04-05 10:00:00 4.478531 317.678285 
2012-04-05 11:00:00 4.706206 335.258633 
2012-04-05 12:00:00 2.457873 8.655838 
+2

這可以擴展到每列的函數列表:'frame.resample('1H',how = {'radiation':[np.sum,np.min],'tamb':np.mean})''。生成的DataFrame在其列上有一個MultiIndex,原始列名稱爲級別0,函數名稱爲級別1. – 2015-05-26 23:36:18

+1

要添加到我以前的評論:而不是每列的函數列表,還可以使用字典,其中的關鍵字是新的列名,值是要使用的函數:'frame.resample('1H',how = {'radiation':{'sum_rad':np.sum,'min_rad':np.min} ,'tamb':np.mean})' – 2015-05-27 20:27:38

+0

說明是否要在結果中添加一個新列,例如resample期間每行的count()。 – codingknob 2016-03-29 19:45:38

0

您需要使用groupby這樣:

grouped = frame.groupby(lambda x: x.hour) 
grouped.agg({'radiation': np.sum, 'tamb': np.mean}) 
# Same as: grouped.agg({'radiation': 'sum', 'tamb': 'mean'}) 

與輸出是:

 radiation  tamb 
key_0      
8  298.581107 4.883806 
9  311.176148 4.983705 
10  315.531527 5.343057 
11  288.013876 6.022002 
12  5.527616 8.507670 

所以在本質上,我分裂的小時值,然後計算tamb和平均總計radiation並返回DataFrame(類似於R的ddply)。欲瞭解更多信息,我將檢查文檔頁面groupby以及this博客文章。

編輯:爲了使這個規模的好一點,你可以在一天時間都集團這樣:

grouped = frame.groupby(lambda x: (x.day, x.hour)) 
grouped.agg({'radiation': 'sum', 'tamb': 'mean'}) 
      radiation  tamb 
key_0       
(5, 8) 298.581107 4.883806 
(5, 9) 311.176148 4.983705 
(5, 10) 315.531527 5.343057 
(5, 11) 288.013876 6.022002 
(5, 12) 5.527616 8.507670 
3

您也可以使用下采樣的pandas.DateRange objectsasof方法。

In [21]: hourly = pd.DateRange(datetime.datetime(2012, 4, 5, 8, 0), 
...       datetime.datetime(2012, 4, 5, 12, 0), 
...       offset=pd.datetools.Hour()) 

In [22]: frame.groupby(hourly.asof).size() 
Out[22]: 
key_0 
2012-04-05 08:00:00 60 
2012-04-05 09:00:00 60 
2012-04-05 10:00:00 60 
2012-04-05 11:00:00 60 
2012-04-05 12:00:00 1 
In [23]: frame.groupby(hourly.asof).agg({'radiation': np.sum, 'tamb': np.mean}) 
Out[23]: 
        radiation tamb 
key_0         
2012-04-05 08:00:00 271.54  4.491 
2012-04-05 09:00:00 266.18  5.253 
2012-04-05 10:00:00 292.35  4.959 
2012-04-05 11:00:00 283.00  5.489 
2012-04-05 12:00:00 0.5414  9.532 
+0

+1使用'DateRange.asof' – diliop 2012-04-05 02:48:37

3

吊胃口你,在大熊貓0.8.0(下重發展,在timeseries分支在GitHub上),你就可以做到:

In [5]: frame.convert('1h', how='mean') 
Out[5]: 
        radiation  tamb 
2012-04-05 08:00:00 7.840989 8.446109 
2012-04-05 09:00:00 4.898935 5.459221 
2012-04-05 10:00:00 5.227741 4.660849 
2012-04-05 11:00:00 4.689270 5.321398 
2012-04-05 12:00:00 4.956994 5.093980 

上述方法是正確的與當前生產版本的熊貓戰略。

+0

謝謝,但我想有可能會像'frame.convert( '1H' 什麼, how = {'radiation':'sum,'tamb':'mean'})'。這是0.8中的一個選項嗎? – bmu 2012-04-08 10:30:22

+0

@ Wes McKinney這應該是0.8的「resample」,不是嗎? – bmu 2012-06-15 20:58:51

+0

如果你想更新你的答案,我會接受它。否則你應該將其刪除,因爲它會將用戶指向錯誤的方向。 – bmu 2012-10-13 08:23:10

相關問題