【问题标题】:Pandas hasnans returns wrong value for column containing NaN valuesPandas hasnans 为包含 NaN 值的列返回错误值
【发布时间】:2019-10-01 17:54:45
【问题描述】:

我有一个大约有一个 DataFrame。 200 列,7000 行。列 B 完全由 NaN 值组成,除了中间的大约 400 行。

总而言之,B 列如下所示(为简洁起见):

      B
 1  NaN
 2  NaN
 3   75
 4   83
 5  NaN
 6  NaN

但是,当我编写如下代码时,hasnans 属性似乎具有错误的值。是我错误地使用了属性还是什么?

df['B'].hasnans

返回 False

编辑: 下面是我要导入 pandas 的 CSV 文件的一个小样本。该列仍然无法找到 NaN 值。精明的观察者会注意到列标题中B 周围的空格。这是意料之中的事,而不是问题所在。

"  DATE       TIME  ","  A  ","  C  ","  B  "
12/11/2018 15:44:36,     5448,     0.00,      NaN
12/11/2018 15:44:36,     5448,     0.00,      NaN
12/11/2018 15:44:36,     5448,     0.00,      NaN
12/11/2018 15:44:36,     5448,     0.00,      NaN
12/11/2018 15:45:07,     5448,     0.00,      NaN
12/11/2018 15:45:08,     5448,     0.00,      NaN
12/11/2018 15:45:08,     5448,     0.00,      NaN
12/11/2018 15:45:09,     5448,     0.00,      NaN
12/11/2018 15:45:09,     5448,     0.00,      NaN

【问题讨论】:

  • 我复制并粘贴了您的确切 df 和代码并返回 True。在您的实例中,它们可能是 NaN 作为字符串。将 dtype 更改为 int 并重试。
  • 我认为您的意思是将 dtype 更改为 float
  • 是的,我做到了,将 dtype 更改为 float 并重试,谢谢

标签: python python-3.x pandas dataframe nan


【解决方案1】:

在我看来,它显示为 false,因为您的列中的 "NaN" 值是 "NaN" 而不是 np.nan,因此我猜该列的数据类型可能是“对象”。因此,您必须将 "NaN" 值转换为 np.nan,以便列的对象可以是 int 或 float,并且 hasnans 将返回正确的布尔值。

首先,

df[df["B"] == "NaN"] = np.nan #it will convert "NaN" values into np.nan

现在您可以使用 hasnansisnull().any() 来检查 NaN 值

干杯!

【讨论】:

    【解决方案2】:

    考虑

    "  DATE       TIME  ","  A  ","  C  ","  B  "
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:45:07,     5448,     0.00,      NaN
    12/11/2018 15:45:08,     5448,     0.00,      NaN
    12/11/2018 15:45:08,     5448,     0.00,      NaN
    12/11/2018 15:45:09,     5448,     0.00,      NaN
    12/11/2018 15:45:09,     5448,     0.00,      NaN
    

    作为您作为 pandas 数据框导入的 .csv 文件,您必须注意您正在寻找的真实值。

    事实上:

    import pandas as pd
    import numpy as np
    
    df = pd.read_csv('filename.csv', header=0)
    
    df['  B  '].replace('      NaN', np.nan, inplace=True)
    df['  B  '].hasnans
    

    返回:

    True
    

    【讨论】:

    • 您的解决方案运行良好,但空格数不同的情况除外。我将它概括为\sNaN 的正则表达式并设置了正则表达式标志,它按预期工作。
    【解决方案3】:

    当您读入 csv 时,您应该使用 skipinitialspace 选项来删除数据中的前导空格。请注意,由于列名用引号引起来,因此它们周围的空格将保留

    # make fake csv
    from io import StringIO
    
    mock_csv = StringIO()
    mock_csv.write("""\
    "  DATE       TIME  ","  A  ","  C  ","  B  "
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:44:36,     5448,     0.00,      NaN
    12/11/2018 15:45:07,     5448,     0.00,      NaN
    12/11/2018 15:45:08,     5448,     0.00,      NaN
    12/11/2018 15:45:08,     5448,     0.00,      NaN
    12/11/2018 15:45:09,     5448,     0.00,      NaN
    12/11/2018 15:45:09,     5448,     0.00,      NaN
    """)
    mock_csv.seek(0)
    
    # disregard initial whitespace
    df = pd.read_csv(mock_csv, skipinitialspace=True)
    assert df['  B  '].hasnans
    

    请参阅文档here

    【讨论】:

    • 你的回答给出了最简洁的解决方法,所以你得到了复选标记。
    猜你喜欢
    • 2017-11-02
    • 2016-12-14
    • 2018-11-02
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多