Python 使用一定数量的NaN计算连续值是可以接受的
对于计算满足条件的连续值,有几个很好的答案,但我似乎找不到一个同时允许一定数量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
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在跑步中计算!加上解释。哇,比我最后想到的要优雅得多!哇,比我最后想到的要优雅得多!