重新采样时间序列,不包括nan数据

时间:2014-09-03 02:20:17

标签: pandas resampling

我有一个每日数据时间序列,其中有许多NaN值。我想重新采样每月数据,只考虑少于10天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的NaN值超过10,因此结果必须是NaN。

由于

2 个答案:

答案 0 :(得分: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来确定超过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

答案 1 :(得分:1)

你可以预先过滤这些组(使用与@Andy Hayden类似的算法)。不确定这是不是更糟糕!

这是0.14.0中的新功能(在先前版本中你可以pd.TimeGrouper('1MS')

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

过滤并仅保留列满足&lt;的标准的组。 10个 然后进行重新采样(这是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然后重新连接,因为filter适用于整个组。