如果有n个连续的NaN值,如何检测每月数据并将其转换为NaN



我有这个df:

CODE      DATE     TMAX
0        000130 1963-09-01   NaN
1        000130 1963-09-02  29.4
2        000130 1963-09-03  27.8
3        000130 1963-09-04  25.0
4        000130 1963-09-05  27.8
...        ...   ...
7393858  158328 2020-12-27  12.2
7393859  158328 2020-12-28   8.8
7393860  158328 2020-12-29   NaN
7393861  158328 2020-12-30  10.3
7393862  158328 2020-12-31   9.2
[7393863 rows x 3 columns]

如果一个月内有5个或更多连续的NaN,我想将df['TMAX']的值转换为NaN。这必须按月份和代码进行。

例如:

CODE      DATE     TMAX   
0        000130 1963-09-01   NaN
1        000130 1963-09-02   NaN
2        000130 1963-09-03   NaN
3        000130 1963-09-04   NaN
4        000130 1963-09-05   NaN
5        000130 1963-09-06  27.8
6        000130 1963-09-07  27.8
7        000130 1963-09-08  27.8
8        000130 1963-09-09  27.8
...        ...   ...

预期df:

CODE      DATE     TMAX   
0        000130 1963-09-01   NaN
1        000130 1963-09-02   NaN
2        000130 1963-09-03   NaN
3        000130 1963-09-04   NaN
4        000130 1963-09-05   NaN
5        000130 1963-09-06   NaN
6        000130 1963-09-07   NaN
7        000130 1963-09-08   NaN
8        000130 1963-09-09   NaN
...        ...   ...

所以我得到了这个代码:

def consecutivenan(d, n=5):
if d.isnull().astype(int).groupby(d.notnull().astype(int).cumsum()).sum().ge(n).any():
return np.nan 
else:
return d

df["TMAX"] = df.groupby(["CODE", df.DATE.dt.year, df.DATE.dt.month], as_index=False)["TMAX"].transform(consecutivenan, n=5)

它工作得很好,但处理代码需要15分钟。

你有什么建议/代码可以让这个代码更高效、更快吗?

PD:我有一台24GB内存、2.7Ghz、4核的笔记本电脑。在文件中,我有700万行,这就是为什么这可能需要太长时间。

您有正确的逻辑,但代码可以简化。您不需要计算isnull/notnull的两倍,也不需要将布尔值转换为整数。

我还在这里测试cumcount而不是sum

你能尝试一下这种潜在的改进吗?

df['DATE'] = pd.to_datetime(df['DATE'])
def consecutivenan(d, n=5):
s = d.notnull()
if s.groupby(s.cumsum()).cumcount().eq(n-1).any():
return np.nan 
else:
return d
df["TMAX"] = df.groupby(["CODE", df['DATE'].dt.to_period('M')], as_index=False)["TMAX"].transform(consecutivenan, n=5)

输出:

CODE       DATE  TMAX
0   130 1963-09-01   NaN
1   130 1963-09-02   NaN
2   130 1963-09-03   NaN
3   130 1963-09-04   NaN
4   130 1963-09-05   NaN
5   130 1963-09-06   NaN
6   130 1963-09-07   NaN
7   130 1963-09-08   NaN
8   130 1963-09-09   NaN

最新更新