2014-09-03 72 views
2

我有一个每日数据时间系列,其中有许多NaN值。我想重新采样月度数据,仅记录少于10天NaN值的月份。不包含nan数据的重采样时间系列

我使用重采样功能的尝试,通过这种方式:

df = 
Date   Sr_1 Sr_2 Sr_3 
01/12/1978 32.2 20.8 NaN 
02/12/1978 32.2 20.6 NaN 
03/12/1978 31.6 22  NaN 
04/12/1978 28.2 19.4 NaN 
05/12/1978 29.8 22.8 24.6 
06/12/1978 32  22.2 25.8 
07/12/1978 32.8 23.2 NaN 
08/12/1978 29.8 NaN  26.8 
09/12/1978 31.4 21.4 25.4 
10/12/1978 28.8 24  NaN 
11/12/1978 30.8 20  NaN 
12/12/1978 32  24  25.6 
13/12/1978 33  23.2 25.8 
14/12/1978 32.4 22.4 24.6 
15/12/1978 30  20.6 NaN 
16/12/1978 32.6 21.2 NaN 
17/12/1978 33  23.4 NaN 
18/12/1978 30.4 20.4 26.4 
19/12/1978 32  22.2 NaN 
20/12/1978 32.2 NaN  NaN 
21/12/1978 32.8 22.8 NaN 
22/12/1978 32  22.2 NaN 
23/12/1978 32.2 NaN  NaN 
24/12/1978 31.4 NaN  NaN 
25/12/1978 33  NaN  25.6 
26/12/1978 33.4 20.6 NaN 
27/12/1978 33.6 22.2 NaN 
28/12/1978 33.6 23.4 NaN 
29/12/1978 33.8 23.4 NaN 
30/12/1978 33.2 NaN  25.2 
31/12/1978 33.6 23.4 25.2 
df.resample('1MS', how='mean') 

结果是:

01/12/1978 31.9 22.1 25.5 

但Sr_3有更多的超过10个NaN值,所以结果为m你是NaN。

谢谢

回答

1

这里是一个hackyish的方式。首先计算NaN的数量,然后在哪里使用NaN。

In [11]: g = df1.groupby(pd.TimeGrouper('1MS')) 

注:使用isnullsum计数。

In [12]: g.apply(lambda x: pd.isnull(x).sum()).unstack(1) # Note: columns match res 
Out[12]: 
      Sr_1 Sr_2 Sr_3 
Date 
1978-01-01  0  0  1 
1978-02-01  0  0  1 
1978-03-01  0  0  1 
1978-04-01  0  0  1 
1978-05-01  0  0  0 
1978-06-01  0  0  0 
1978-07-01  0  0  1 
1978-08-01  0  1  0 
1978-09-01  0  0  0 
1978-10-01  0  0  1 
1978-11-01  0  0  1 
1978-12-01  0  5 13 

In [13]: under_ten_nan = g.apply(lambda x: pd.isnull(x).sum()).unstack(1) <= 10 

使用where为NaN那些条目10:

In [14]: res.where(under_ten_nan) 
Out[14]: 
      Sr_1 Sr_2 Sr_3 
Date 
1978-01-01 32.20 20.80 NaN 
1978-02-01 32.20 20.60 NaN 
1978-03-01 31.60 22.00 NaN 
1978-04-01 28.20 19.40 NaN 
1978-05-01 29.80 22.80 24.6 
1978-06-01 32.00 22.20 25.8 
1978-07-01 32.80 23.20 NaN 
1978-08-01 29.80 NaN 26.8 
1978-09-01 31.40 21.40 25.4 
1978-10-01 28.80 24.00 NaN 
1978-11-01 30.80 20.00 NaN 
1978-12-01 32.51 22.36 NaN 
+0

谢谢,直觉上我是这样走的。 – anvelascos 2014-09-16 13:09:30

0

可以预过滤器组(使用类似算法中作为@Andy海登)。不知道这是否更加黑客!

这在0.14.0是新的(您可以在pd.TimeGrouper('1MS')在以前的版本

In [20]: g = pd.Grouper(freq='1MS') 

筛选,只保留组,其中列有满足10 <将NaN 的标准,然后做了重新取样(这是什么groupby(g).mean()一样)

In [28]: pd.concat([ 
        df.groupby(g)[c].filter(lambda x: x.isnull().sum()<10).groupby(g).mean() 
        for c in df.columns ],axis=1) 

Out[28]: 
      Sr_1 Sr_2 Sr_3 
Date       
1978-01-01 32.20 20.80 NaN 
1978-02-01 32.20 20.60 NaN 
1978-03-01 31.60 22.00 NaN 
1978-04-01 28.20 19.40 NaN 
1978-05-01 29.80 22.80 24.6 
1978-06-01 32.00 22.20 25.8 
1978-07-01 32.80 23.20 NaN 
1978-08-01 29.80 NaN 26.8 
1978-09-01 31.40 21.40 25.4 
1978-10-01 28.80 24.00 NaN 
1978-11-01 30.80 20.00 NaN 
1978-12-01 32.51 22.36 NaN 

这有许多工作要做柱columm然后concatted因为过滤器适用于整个组。