2016-02-28 72 views
2

我正在處理由不完整時間序列組成的每小時監測數據,即一年中(或幾年內)數小時的數據將從我的數據框中消失。如何確定使用熊貓數據框捕獲數據?

我想確定數據捕獲,即一個月,一個季節或一年中存在的值的百分比。

這適用於下面的代碼(用於爲月度重採樣編寫的演示) - 但是那段代碼看起來效率不高,因爲我需要創建第二個小時數據幀,並且需要重新採樣兩個數據幀。

有沒有更優雅的解決方案呢?

import numpy as np 
import pandas as pd 

# create dummy series 
t1 = pd.date_range(start="1997-01-01 05:00", end="1997-04-25 17:00", freq="H") 
t2 = pd.date_range(start="1997-06-11 15:00", end="1997-06-15 12:00", freq="H") 
t3 = pd.date_range(start="1997-06-18 00:00", end="1997-08-22 23:00", freq="H") 

df1 = pd.DataFrame(np.random.randn(len(t1)), index=t1) 
df2 = pd.DataFrame(np.random.randn(len(t2)), index=t2) 
df3 = pd.DataFrame(np.random.randn(len(t3)), index=t3) 

df = pd.concat((df1, df2, df3)) 

# create time index with complete hourly coverage over entire years 
tstart = "%i-01-01 00:00"%(df.index.year[0]) 
tend = "%i-12-31 23:00"%(df.index.year[-1]) 
tref = pd.date_range(start=tstart, end=tend, freq="H") 
dfref = pd.DataFrame(np.zeros(len(tref)), index=tref) 

# count number of values in reference dataframe and actual dataframe 
# Example: monthly resampling 
cntref = dfref.resample("MS", "count") 
cnt = df.resample("MS", "count").reindex(cntref.index).fillna(0) 

for i in range(len(cnt.index)): 
    print cnt.index[i], cnt.values[i], cntref.values[i], cnt.values[i]/cntref.values[i] 

回答

0

由於沒有進一步的建議,它看起來好像最初發布的解決方案是最有效的。

1

pandasTimedelta將這樣的伎倆:

# Time delta between rows of the df 
df['index'] = df.index 
pindex = df['index'].shift(1) 
delta = df['index'] - pindex 

# Any delta > 1H means a missing data period 
missing_delta = delta[delta > pd.Timedelta('1H')] 

# Sum of missing data periods divided by total period 
ratio_missing = missing_delta.sum()/(df.index[-1] - df.index[0]) 
+0

這個解決方案很有趣也很快,但不幸的是我沒有做我想做的事情,因爲我需要每個月的數據捕獲,而不僅僅是總分數。但是瞭解Timedelta很好。 – maschu

1

您可以使用TimeGrouper。

# Create an hourly index spanning the range of your data. 
idx = pd.date_range(pd.Timestamp(df.index[0].strftime('%Y-%m-%d %H:00')), 
        pd.Timestamp(df.index[-1].strftime('%Y-%m-%d %H:00')), 
        freq='H') 

# Use TimeGrouper to calculate the fraction of observations from `df` that are in the 
# hourly time index. 
>>> (df.groupby(pd.TimeGrouper('M')).size()/
    pd.Series(idx).reindex(idx).groupby(pd.TimeGrouper('M')).size()) 
1997-01-31 1.000000 
1997-02-28 1.000000 
1997-03-31 1.000000 
1997-04-30 0.825000 
1997-05-31 0.000000 
1997-06-30 0.563889 
1997-07-31 1.000000 
1997-08-31 1.000000 
Freq: M, dtype: float64 
+0

這有效(如果我在上面的示例中調整代碼以計算idx爲tref)。但是,在我的電腦上,它需要原始解決方案的兩倍左右。分組看起來本質上很慢 - 如果分組或操作更復雜,它的優勢可能會帶來回報。 – maschu