我有一个每日数据时间序列,其中有许多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。
由于
答案 0 :(得分:1)
这是一种hackyish方式。首先计算NaN的数量,然后使用那些NaN那些。
In [11]: g = df1.groupby(pd.TimeGrouper('1MS'))
注意:使用isnull
和sum
进行统计。
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适用于整个组。