簡體   English   中英

用 Pandas 識別連續的 NaN

[英]Identifying consecutive NaNs with Pandas

我正在閱讀一堆 CSV 文件(隨時間變化的水位測量數據)以對它們進行各種分析和可視化。

由於各種我無法控制的原因,這些時間序列經常有缺失數據,所以我做了兩件事:

我把它們一共算了

Rlength = len(RainD)   # Counts everything, including NaN
Rcount = RainD.count() # Counts only valid numbers
NaN_Number = Rlength - Rcount

如果丟失的數據超過某個閾值,則丟棄數據集:

Percent_Data = Rlength/100
Five_Percent = Percent_Data*5
if NaN_Number > Five_Percent:
    ...

如果 NaN 的數量足夠小,我想用

RainD.level = RainD.level.fillna(method='pad', limit=2)

現在的問題是:這是月度數據,所以如果我有兩個以上連續的 NaN,我也想丟棄數據,因為這意味着我“猜測”了整個賽季,甚至更多。

fillna文檔並沒有真正提到當連續的 NaN 超過我指定的limit=2時會發生什么,但是當我查看RainD.describe()之前和之后...fillna...並將其與基數進行比較時CSV,很明顯它填充了前兩個 NaN,然后​​將其余部分保持原樣,而不是出錯。

所以,長話短說:

如何使用 Pandas 識別多個連續的 NaN,而不需要一些復雜且耗時的非 Pandas 循環?

您可以使用多個布爾條件來測試當前值和先前值是否為NaN

In [3]:

df = pd.DataFrame({'a':[1,3,np.NaN, np.NaN, 4, np.NaN, 6,7,8]})
df
Out[3]:
    a
0   1
1   3
2 NaN
3 NaN
4   4
5 NaN
6   6
7   7
8   8
In [6]:

df[(df.a.isnull()) & (df.a.shift().isnull())]
Out[6]:
    a
3 NaN

如果您想找到連續的NaNs出現的位置超過 2,您可以執行以下操作:

In [38]:

df = pd.DataFrame({'a':[1,2,np.NaN, np.NaN, np.NaN, 6,7,8,9,10,np.NaN,np.NaN,13,14]})
df
Out[38]:
     a
0    1
1    2
2  NaN
3  NaN
4  NaN
5    6
6    7
7    8
8    9
9   10
10 NaN
11 NaN
12  13
13  14

In [41]:

df.a.isnull().astype(int).groupby(df.a.notnull().astype(int).cumsum()).sum()
Out[41]:
a
1    0
2    3
3    0
4    0
5    0
6    0
7    2
8    0
9    0
Name: a, dtype: int32

如果您希望將其映射回原始索引,或者連續計數 NaN,請使用 Ed 的答案cumsum而不是sum 這對於可視化時間序列中的 NaN 組特別有用:

df = pd.DataFrame({'a':[
    1,2,np.NaN, np.NaN, np.NaN, 6,7,8,9,10,np.NaN,np.NaN,13,14
]})

df.a.isnull().astype(int).groupby(df.a.notnull().astype(int).cumsum()).cumsum()


0     0
1     0
2     1
3     2
4     3
5     0
6     0
7     0
8     0
9     0
10    1
11    2
12    0
13    0
Name: a, dtype: int64

例如,

pd.concat([
        df,
        (
            df.a.isnull().astype(int)
            .groupby(df.a.notnull().astype(int).cumsum())
            .cumsum().to_frame('consec_count')
        )
    ],
    axis=1
)

    a       consec_count
0   1.0     0
1   2.0     0
2   NaN     1
3   NaN     2
4   NaN     3
5   6.0     0
6   7.0     0
7   8.0     0
8   9.0     0
9   10.0    0
10  NaN     1
11  NaN     2
12  13.0    0
13  14.0    0

如果您只想找到連續 NaN 的長度...

# usual imports
import pandas as pd
import numpy as np

# fake data
data = pd.Series([np.nan,1,1,1,1,1,np.nan,np.nan,np.nan,1,1,np.nan,np.nan])

# code 
na_groups = data.notna().cumsum()[data.isna()]
lengths_consecutive_na = missing_groups.groupby(missing_groups).agg(len)
longest_na_gap = lengths_consecutive_na.max()

暫無
暫無

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

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