簡體   English   中英

如何根據連續和非連續的 NaN 將數據轉換為 NaN?

[英]How to convert data to NaN based on consecutive and non consecutive NaNs?

我有這個df

       CODE      DATE     TMAX  
0      000130 1991-01-01  32.6  
1      000130 1991-01-02  31.2  
2      000130 1991-01-03  32.0   
3      000130 1991-01-04  32.2  
4      000130 1991-01-05  30.5  
...      ...     ...       ... 
10865  000130 2020-12-31   NaN   
10866  000132 1991-01-01  35.2   
10867  000132 1991-01-02  34.6   
10868  000132 1991-01-03  35.8   
10869  000132 1991-01-04  34.8   
10870  000132 1991-01-05  34.8  
10871  000132 1991-01-06  34.8   
10872  000132 1991-01-07  34.8   
10873  000132 1991-01-08  34.8
...      ...     ...       ...  

TMAX月有 5 個或更多連續 NaN 值或當月有 11 個或更多非連續 NaN 值時,我才想將一個月的TMAX數據轉換為 NaN。 我只需要滿足一個條件即可將月份轉換為 NaN。

例子:

       CODE      DATE     TMAX  
0      000130 1991-02-01  NaN  
1      000130 1991-02-02  NaN  
2      000130 1991-02-03  NaN   
3      000130 1991-02-04  NaN  
4      000130 1991-02-05  NaN  
5      000130 1991-02-06  33.8   
6      000132 1991-02-07  35.2   
7      000132 1991-02-08  NaN   
8      000132 1991-02-09  NaN   
9      000132 1991-02-10  NaN   
10     000132 1991-02-11  NaN  
11     000132 1991-02-12  NaN   
12     000132 1991-02-13  NaN   
13     000132 1991-02-14  34.8
...    ...    ...         ...

期望值:

       CODE      DATE     TMAX  
0      000130 1991-02-01  NaN  
1      000130 1991-02-02  NaN  
2      000130 1991-02-03  NaN   
3      000130 1991-02-04  NaN  
4      000130 1991-02-05  NaN  
5      000130 1991-02-06  NaN   
6      000132 1991-02-07  NaN   
7      000132 1991-02-08  NaN   
8      000132 1991-02-09  NaN   
9      000132 1991-02-10  NaN   
10     000132 1991-02-11  NaN  
11     000132 1991-02-12  NaN   
12     000132 1991-02-13  NaN   
13     000132 1991-02-14  NaN
...    ...    ...         ...

所以我寫了這段代碼:

s = df['TMAX'].isnull().groupby([df['CODE'], df['DATE'].astype('datetime64[M]')]).transform('sum')
df['TMAX'] = df['TMAX'].mask(s.ge(11))

但是,當一個月中有 11 個或更多非連續 NaN 時,此代碼僅將一個月的TMAX數據轉換為 NaN。 我需要這兩個條件。 你介意幫我嗎?

提前致謝。

在我看來,您的代碼不計算連續值,而是計算每個組和每個月的所有非NaN

對於連續,它更復雜:

print (df)
    CODE        DATE  TMAX
0    130  1991-02-01   NaN < 5 consecutive NaN per 130 per 1991-02
1    130  1991-02-02   NaN
2    130  1991-02-03   NaN
3    130  1991-02-04   NaN
4    130  1991-02-05   NaN
5    130  1991-02-06  33.8
6    132  1991-02-07  35.2 < non 5 consecutive NaN per 132 per 1991-02
7    132  1991-02-08   NaN
8    132  1991-02-09   NaN
9    132  1991-02-10   NaN
10   132  1991-02-11   NaN
11   132  1991-02-12  34.8
12   132  1991-02-13   NaN
13   132  1991-02-14  34.8
14   133  1991-02-01   2.0 < 12 consecutive non NaN per 133 per 1991-02
15   133  1991-02-02   2.0
16   133  1991-02-03   2.0
17   133  1991-02-04   2.0
18   133  1991-02-05   2.0
19   133  1991-02-06  33.8
20   133  1991-02-07  35.2
21   133  1991-02-08   2.0
22   133  1991-02-09   2.0
23   133  1991-02-10   2.0
24   133  1991-02-11   2.0
25   133  1991-02-12   1.0
26   133  1991-02-13   NaN
27   133  1991-02-14  34.8

df['DATE'] = pd.to_datetime(df['DATE'])

m = df['TMAX'].notna()

#consecutive groups
a = m.cumsum().mask(m)
b = (~m).cumsum().mask(~m)

y = df.DATE.dt.year 
m = df.DATE.dt.month

#count per consecutive groups, CODE and month
s1 = a.groupby([a, df['CODE'], y, m]).transform('size')
s2 = b.groupby([b, df['CODE'], y, m]).transform('size')

#chain and test if at least one value match
m = ((s1.ge(5) | s2.ge(11))
        .groupby([df['CODE'], y, m])
        .transform('any'))

df['TMAX'] = df['TMAX'].mask(m)

print (df)
    CODE       DATE  TMAX
0    130 1991-02-01   NaN
1    130 1991-02-02   NaN
2    130 1991-02-03   NaN
3    130 1991-02-04   NaN
4    130 1991-02-05   NaN
5    130 1991-02-06   NaN
6    132 1991-02-07  35.2 <- non consecutive - no change
7    132 1991-02-08   NaN
8    132 1991-02-09   NaN
9    132 1991-02-10   NaN
10   132 1991-02-11   NaN
11   132 1991-02-12  34.8
12   132 1991-02-13   NaN
13   132 1991-02-14  34.8
14   133 1991-02-01   NaN
15   133 1991-02-02   NaN
16   133 1991-02-03   NaN
17   133 1991-02-04   NaN
18   133 1991-02-05   NaN
19   133 1991-02-06   NaN
20   133 1991-02-07   NaN
21   133 1991-02-08   NaN
22   133 1991-02-09   NaN
23   133 1991-02-10   NaN
24   133 1991-02-11   NaN
25   133 1991-02-12   NaN
26   133 1991-02-13   NaN
27   133 1991-02-14   NaN

使用groupby嘗試以下操作:

s = df['TMAX'].isnull().groupby([df['CODE'], df['DATE'].astype('datetime64[M]')]).transform('sum')
n = df['TMAX'].groupby([df['CODE'], df['DATE'].astype('datetime64[M]'), df['TMAX'].replace(np.nan, 0).diff().ne(0).cumsum()]).transform('size')
df['TMAX'] = np.nan if ((s.sum() > 11) | n.ge(5)).any() else df['TMAX']
print(df)

輸出:

    CODE        DATE  TMAX
0    130  1991-02-01   NaN
1    130  1991-02-02   NaN
2    130  1991-02-03   NaN
3    130  1991-02-04   NaN
4    130  1991-02-05   NaN
5    130  1991-02-06   NaN
6    132  1991-02-07   NaN
7    132  1991-02-08   NaN
8    132  1991-02-09   NaN
9    132  1991-02-10   NaN
10   132  1991-02-11   NaN
11   132  1991-02-12   NaN
12   132  1991-02-13   NaN
13   132  1991-02-14   NaN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM