【问题标题】:How to filter by NaN in string column in pandas? [duplicate]如何在熊猫的字符串列中按 NaN 过滤? [复制]
【发布时间】:2016-09-06 13:09:32
【问题描述】:

我使用的是熊猫 0.18。我已经使用 pd.read_csv() 从 CSV 加载了一个数据框,看起来 CSV 中的空单元格在数据框中加载为 NaN

现在我想查找特定列中具有空值的行数,但我很苦恼。

这是我的数据框:

      ods         id provider
0  A86016        NaN     emis
1  L81042     463061      NaN
2  C84013        NaN      tpp
3  G82228     462941     emis
4  C81083        NaN      tpp

这是我从df.describe() 得到的:

           ods         id provider
count     9897       7186     9022
unique    8066        192        4
top     N83028     463090     emis
freq         7        169     4860

我想获取 CSV 中 provider 为空的所有行。这是我尝试过的:

>>> print len(df[df.provider == 'NaN'])
0
>>> print len(df[df.provider == np.nan])
0

我可以看到那里有一些 NaN 值(例如第 1 行),那么给出了什么?

另外,为什么 pandas 将字符串列中的空值(如 provider)转换为 NaN - 将它们转换为空字符串不是更有意义吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用isnull 比较NaN

    df = pd.DataFrame({'ods': {0: 'A86016', 1: 'L81042', 2: 'C84013', 3: 'G82228', 4: 'C81083'}, 
                       'id': {0: np.nan, 1: 463061.0, 2: np.nan, 3: 462941.0, 4: np.nan}, 
                       'provider': {0: 'emis', 1: np.nan, 2: 'tpp', 3: 'emis', 4: 'tpp'}})
    
    print df
             id     ods provider
    0       NaN  A86016     emis
    1  463061.0  L81042      NaN
    2       NaN  C84013      tpp
    3  462941.0  G82228     emis
    4       NaN  C81083      tpp
    
    print (df[df.provider.isnull()])
    
          ods        id provider
    1  L81042  463061.0      NaN
    
    print len(df[df.provider.isnull()])
    1
    

    如果您需要将NaN 转换为`` 使用fillna

    df.provider.fillna('', inplace=True)
    print df
             id     ods provider
    0       NaN  A86016     emis
    1  463061.0  L81042         
    2       NaN  C84013      tpp
    3  462941.0  G82228     emis
    4       NaN  C81083      tpp
    

    Docs:

    警告

    必须注意,在 python(和 numpy)中,nan 的比较不相等,但 None 的比较。请注意,Pandas/numpy 使用 np.nan != np.nan 这一事实,并将 None 视为 np.nan。

    In [11]: None == None
    Out[11]: True
    
    In [12]: np.nan == np.nan
    Out[12]: False
    

    因此,与上面相比,标量相等比较与 None/np.nan 不提供有用的信息。

    In [13]: df2['one'] == np.nan
    Out[13]: 
    a    False
    b    False
    c    False
    d    False
    e    False
    f    False
    g    False
    h    False
    Name: one, dtype: bool
    

    但如果nan 是字符串:

    df = pd.DataFrame({'ods': {0: 'A86016', 1: 'L81042', 2: 'C84013', 3: 'G82228', 4: 'C81083'}, 
                       'id': {0: np.nan, 1: 463061.0, 2: np.nan, 3: 462941.0, 4: np.nan}, 
                       'provider': {0: 'emis', 1: 'nan', 2: 'tpp', 3: 'emis', 4: 'tpp'}})
    
    print df
          ods        id provider
    0  A86016       NaN     emis
    1  L81042  463061.0      nan
    2  C84013       NaN      tpp
    3  G82228  462941.0     emis
    4  C81083       NaN      tpp
    
    
    print (df[df.provider == 'nan'])
          ods        id provider
    1  L81042  463061.0      nan
    

    你知道为什么 pandas 将空字符串导入为 NaN 而不是空字符串吗?

    docs(我加粗):

    na_values : str, list-likedict,默认 None

    识别为 NA/NaN 的附加字符串。如果 dict 通过,特定的每列 NA 值。默认情况下,以下值被解释为 NaN:'-1.#IND'、'1.#QNAN'、'1.#IND'、'-1.#QNAN'、'#N/AN/A'、' #N/A'、'N/A'、'NA'、'#NA'、'NULL'、'NaN'、'-NaN'、'nan'、'-nan'、''强>。

    【讨论】:

    • 谢谢!再问一个问题,你知道为什么 pandas 将空字符串导入为 NaN 而不是空字符串吗?
    【解决方案2】:

    您可以先存储 na 值,然后删除所有其他值:

    without_na = df['provider'].dropna()
    df[~df.index.isin(without_na.index)]
    

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 1970-01-01
      • 2014-09-22
      • 2023-03-14
      • 2015-09-24
      • 2014-10-03
      • 2019-04-24
      • 2021-03-22
      相关资源
      最近更新 更多