计算连续的NaN值,并获得NaN连续周期的开始和结束日期



我有连续的NaN值周期。我想从连续的NaN值的周期中计算NaN值,并且我还想要NaN值的连续周期的开始和结束日期。

df :
TMIN
2017-01-01 00:00:00      2.5
2017-01-02 00:00:00      NaN
2017-01-03 00:00:00      NaN
2017-01-04 00:00:00      2.2
2018-01-01 00:00:00      NaN
2018-01-02 00:00:00      NaN
2018-01-03 00:00:00      NaN
2018-01-04 00:00:00      5.0
2019-01-01 00:00:00      9.0
2019-01-02 00:00:00      8.0
2019-01-03 00:00:00      2.0
2019-01-04 00:00:00      NaN
2020-01-01 00:00:00      NaN
2020-01-02 00:00:00      NaN
2020-01-03 00:00:00      1.0
2020-01-04 00:00:00      NaN

Expected results :
Start_Date      End date               number of contiguous missing values 
2017-01-02 00:00:00    2017-01-03 00:00:00                2
2018-01-01 00:00:00    2018-01-03 00:00:00                3
2019-01-04 00:00:00    2019-01-04 00:00:00                1
2020-01-01 00:00:00    2020-01-02 00:00:00                2
2020-01-04 00:00:00    2020-01-04 00:00:00                1

我该如何解决这个问题?提前谢谢。

CODE:

s = df.index.to_series()
m1, m2 = s.diff().dt.days.eq(1), df['TMIN'].isna()
out = s[m2].groupby([(~m1).cumsum(), (~m2).cumsum()])
.agg(['first', 'last', 'count']).reset_index(drop=True)

细节:

创建布尔掩码m1m2,使m1表示连续日期之差为1 days的条件,m2表示列TMIN包含NaN值的条件:

>>> m1 
2017-01-01    False
2017-01-02     True
2017-01-03     True
2017-01-04     True
2018-01-01    False
2018-01-02     True
2018-01-03     True
2018-01-04     True
2019-01-01    False
2019-01-02     True
2019-01-03     True
2019-01-04     True
2020-01-01    False
2020-01-02     True
2020-01-03     True
2020-01-04     True
dtype: bool
>>> m2
2017-01-01    False
2017-01-02     True
2017-01-03     True
2017-01-04    False
2018-01-01     True
2018-01-02     True
2018-01-03     True
2018-01-04    False
2019-01-01    False
2019-01-02    False
2019-01-03    False
2019-01-04     True
2020-01-01     True
2020-01-02     True
2020-01-03    False
2020-01-04     True
Name: TMIN, dtype: bool

使用带有上述布尔掩码的cumsum来标识连续的datesNaN值的块:

>>> (~m1).cumsum()
2017-01-01    1
2017-01-02    1
2017-01-03    1
2017-01-04    1
2018-01-01    2
2018-01-02    2
2018-01-03    2
2018-01-04    2
2019-01-01    3
2019-01-02    3
2019-01-03    3
2019-01-04    3
2020-01-01    4
2020-01-02    4
2020-01-03    4
2020-01-04    4
dtype: int64
>>> (~m2).cumsum()
2017-01-01    1
2017-01-02    1
2017-01-03    1
2017-01-04    2
2018-01-01    2
2018-01-02    2
2018-01-03    2
2018-01-04    3
2019-01-01    4
2019-01-02    5
2019-01-03    6
2019-01-04    6
2020-01-01    6
2020-01-02    6
2020-01-03    7
2020-01-04    7
Name: TMIN, dtype: int64

最后group和上述块上datframe的index,并使用firstlastcount进行聚合,得到结果:

>>> out
first       last  count
0 2017-01-02 2017-01-03      2
1 2018-01-01 2018-01-03      3
2 2019-01-04 2019-01-04      1
3 2020-01-01 2020-01-02      2
4 2020-01-04 2020-01-04      1

尝试使用more_iterools(标准python库)

from more_itertools import consecutive_groups
m = df[df['TMIN'].isna()]
l = [list(i) for i in consecutive_groups(m.index.map(pd.Timestamp.toordinal))]
d = {pd.Timestamp.fromordinal(ele):e for e,item in enumerate(l) for ele in item}
out = (pd.Series(m.index,index=m.index.map(d))
.groupby(level=0).agg(['min','max','count']))
#out.columns = ['Start_Date','End date','number of contiguous missing values']

print(out)
min        max  count
0 2017-01-02 2017-01-03      2
1 2018-01-01 2018-01-03      3
2 2019-01-04 2019-01-04      1
3 2020-01-01 2020-01-02      2
4 2020-01-04 2020-01-04      1

相关内容

  • 没有找到相关文章