Python 使用一定数量的NaN计算连续值是可以接受的

Python 使用一定数量的NaN计算连续值是可以接受的,python,pandas,dataframe,Python,Pandas,Dataframe,对于计算满足条件的连续值,有几个很好的答案,但我似乎找不到一个同时允许一定数量NaN的答案 例如,以以下数据帧为例: Date Val1 1900-01-01 NaN 1900-01-02 10 1900-01-03 11 1900-01-04 13 1900-01-05 NaN 1900-01-06 NaN 1900-01-07 17 1900-01-08 2 1900-01-09 NaN 1900-0

对于计算满足条件的连续值,有几个很好的答案,但我似乎找不到一个同时允许一定数量NaN的答案

例如,以以下数据帧为例:

Date           Val1
1900-01-01     NaN
1900-01-02     10
1900-01-03     11
1900-01-04     13
1900-01-05     NaN
1900-01-06     NaN
1900-01-07     17
1900-01-08     2
1900-01-09     NaN
1900-01-10     NaN
1900-01-11     2
1900-01-12     5
1900-01-13     6
理想情况下,我希望计算具有特定值且可接受一定数量的NAN的运行。我可以获得值的计数和运行长度,但如何允许在运行中对一定数量的NaN进行计数

在上述数据框中,如果我们允许两个NAN,并且希望值为10或以上,则运行将从1900-01-01开始,到1900-01-07结束,产生:

Date           Run length
1900-01-01     7
请注意,运行长度为7,因为第一个NaN在运行中计数


我尝试创建两个不同的列,用适当的值计算运行长度,用NaN计算运行长度,但我不确定如何继续。我知道我能和熊猫一起做到,我必须离得很近,但在终点线附近我完全迷失了方向

查找“Val1”不为null的位置。使用它来定位连续的
NaN
s组,但首先要屏蔽原始数据帧,以便我们只计算NaN行

m = df['Val1'].notnull()
s1 = df.where(~m).groupby(m.cumsum())['Date'].transform('count').le(2)
这两个掩码一起可用于指示2个或更少连续
NaN
s的真值

(s1 & ~m)

0      True
1     False
2     False
3     False
4      True
5      True
6     False
7     False
8      True
9      True
10    False
11    False
12    False
dtype: bool
再加上>=10的条件

gps = (s1 & ~m) | df['Val1'].ge(10)
使用此系列进行分组。使用
where
+
dropna
清除所有由不符合条件的事物组成的组

res = (df.where(gps).dropna(subset=['Date'])
         .groupby((~gps).cumsum())
         .agg(['first', 'count']))

#         Date        Val1      
#        first count first count
#0  1900-01-01     7  10.0     4
#1  1900-01-09     2   NaN     0
最后,让我们删除那些仅基于连续NAN的组

res = res.loc[res[('Val1', 'count')].ne(0), 'Date']

#        first  count
#0  1900-01-01      7

查找“Val1”不为null的位置。使用它来定位连续的
NaN
s组,但首先要屏蔽原始数据帧,以便我们只计算NaN行

m = df['Val1'].notnull()
s1 = df.where(~m).groupby(m.cumsum())['Date'].transform('count').le(2)
这两个掩码一起可用于指示2个或更少连续
NaN
s的真值

(s1 & ~m)

0      True
1     False
2     False
3     False
4      True
5      True
6     False
7     False
8      True
9      True
10    False
11    False
12    False
dtype: bool
再加上>=10的条件

gps = (s1 & ~m) | df['Val1'].ge(10)
使用此系列进行分组。使用
where
+
dropna
清除所有由不符合条件的事物组成的组

res = (df.where(gps).dropna(subset=['Date'])
         .groupby((~gps).cumsum())
         .agg(['first', 'count']))

#         Date        Val1      
#        first count first count
#0  1900-01-01     7  10.0     4
#1  1900-01-09     2   NaN     0
最后,让我们删除那些仅基于连续NAN的组

res = res.loc[res[('Val1', 'count')].ne(0), 'Date']

#        first  count
#0  1900-01-01      7

第一个NaN呢?第一个NaN会被计算在内!添加到解释中。第一个NaN呢?第一个NaN在跑步中计算!加上解释。哇,比我最后想到的要优雅得多!哇,比我最后想到的要优雅得多!