【问题标题】:How to count the NaN values in a column in pandas DataFrame如何计算pandas DataFrame中列中的NaN值
【发布时间】:2014-12-03 16:07:34
【问题描述】:

我想在我的数据的每一列中找到NaN 的数量,以便如果它的NaN 少于某个阈值,我可以删除一列。我看了看,但找不到任何功能。 value_counts 对我来说太慢了,因为大多数值都是不同的,我只对 NaN 计数感兴趣。

【问题讨论】:

  • 我在搜索“如何计算列中的 NaN 值”,但实际上答案是“我想在我数据的每一列”。幸运的是,其中一个 cmets 实际上提供了答案。典型的“正文与标题不匹配,因此答案与标题不匹配”。
  • @Rishabh 注意df.info() 不返回DataFame,该方法只打印信息。
  • 感谢@joris - 只需一个简单的df.info() 即可提供每列的数据类型和非空计数

标签: python pandas dataframe


【解决方案1】:

你可以试试:

In [1]: s = pd.DataFrame('a'=[1,2,5, np.nan, np.nan,3],'b'=[1,3, np.nan, np.nan,3,np.nan])

In [4]: s.isna().sum()   
Out[4]: out = {'a'=2, 'b'=3} # so row by row the .sum of nan

如果需要,nans 的总数:

In [5]: s.isna().sum().sum()
Out[6]: out = 5  #the inline sum of Out[4] 

【讨论】:

    【解决方案2】:

    您可以使用 df.iteritems() 循环遍历数据框。在 for 循环中设置条件以计算每列的 NaN 值百分比,并删除那些包含 NaN 值超过设置阈值的值:

    for col, val in df.iteritems():
        if (df[col].isnull().sum() / len(val) * 100) > 30:
            df.drop(columns=col, inplace=True)
    

    【讨论】:

      【解决方案3】:

      我编写了一个简短的函数 (Python 3) 来生成 .info 作为 pandas 数据帧,然后可以将其写入 excel:

      df1 = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]}) 
      def info_as_df (df):
          null_counts = df.isna().sum()
          info_df = pd.DataFrame(list(zip(null_counts.index,null_counts.values))\
                                               , columns = ['Column', 'Nulls_Count'])
          data_types = df.dtypes
          info_df['Dtype'] = data_types.values
          return info_df
      print(df1.info())
      print(info_as_df(df1))
      

      这给出了:

      <class 'pandas.core.frame.DataFrame'>
      RangeIndex: 3 entries, 0 to 2
      Data columns (total 2 columns):
       #   Column  Non-Null Count  Dtype  
      ---  ------  --------------  -----  
       0   a       2 non-null      float64
       1   b       1 non-null      float64
      dtypes: float64(2)
      memory usage: 176.0 bytes
      None
        Column  Nulls_Count    Dtype
      0      a            1  float64
      1      b            2  float64
      

      【讨论】:

        【解决方案4】:
        df.isnull().sum() 
              //type: <class 'pandas.core.series.Series'>
        

        df.column_name.isnull().sum()
             //type: <type 'numpy.int64'>
        

        【讨论】:

          【解决方案5】:

          我使用这个循环来计算每一列的缺失值:

          # check missing values
          import numpy as np, pandas as pd
          for col in df:
                print(col +': '+ np.str(df[col].isna().sum()))
          

          【讨论】:

            【解决方案6】:

            根据投票最多的答案,我们可以轻松定义一个函数,该函数为我们提供一个数据框来预览缺失值和每列中缺失值的百分比:

            def missing_values_table(df):
                mis_val = df.isnull().sum()
                mis_val_percent = 100 * df.isnull().sum() / len(df)
                mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)
                mis_val_table_ren_columns = mis_val_table.rename(
                columns = {0 : 'Missing Values', 1 : '% of Total Values'})
                mis_val_table_ren_columns = mis_val_table_ren_columns[
                    mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(
                '% of Total Values', ascending=False).round(1)
                print ("Your selected dataframe has " + str(df.shape[1]) + " columns.\n"      
                    "There are " + str(mis_val_table_ren_columns.shape[0]) +
                        " columns that have missing values.")
                return mis_val_table_ren_columns
            

            【讨论】:

            • 类似 df.stb.missing() 的东西?您必须导入 sidetable 模块才能正常工作!
            • 这太棒了
            【解决方案7】:

            df.isnull().sum() 将给出缺失值的按列总和。

            如果您想知道特定列中缺失值的总和,则可以使用以下代码:df.column.isnull().sum()

            【讨论】:

              【解决方案8】:

              对于第一个部分计数NaN,我们有多种方法。

              方法一count,由于count会忽略与size不同的NaN

              print(len(df) - df.count())
              

              方法 2 isnull / isna 链与sum

              print(df.isnull().sum())
              #print(df.isna().sum())
              

              方法 3 describe / info :注意这将输出 'notnull' 值计数

              print(df.describe())
              #print(df.info())
              

              来自numpy的方法

              print(np.count_nonzero(np.isnan(df.values),axis=0))
              

              对于问题的第 2nd 部分,如果我们想通过 thresh 删除列,我们可以尝试使用dropna

              thresh, optional 需要很多非 NA 值。

              Thresh = n # no null value require, you can also get the by int(x% * len(df))
              df = df.dropna(thresh = Thresh, axis = 1)
              

              【讨论】:

                【解决方案9】:

                希望对你有帮助,

                import pandas as pd
                import numpy as np
                df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan],'c':[np.nan,2,np.nan], 'd':[np.nan,np.nan,np.nan]})
                

                df.isnull().sum()/len(df) * 100
                

                Thres = 40
                (df.isnull().sum()/len(df) * 100 ) < Thres
                

                【讨论】:

                  【解决方案10】:

                  下面将按降序打印所有 Nan 列。

                  df.isnull().sum().sort_values(ascending = False)
                  

                  下面将按降序打印前 15 个 Nan 列。

                  df.isnull().sum().sort_values(ascending = False).head(15)
                  

                  【讨论】:

                    【解决方案11】:

                    对于您的任务,您可以使用 pandas.DataFrame.dropna (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html):

                    import pandas as pd
                    import numpy as np
                    
                    df = pd.DataFrame({'a': [1, 2, 3, 4, np.nan],
                                       'b': [1, 2, np.nan, 4, np.nan],
                                       'c': [np.nan, 2, np.nan, 4, np.nan]})
                    df = df.dropna(axis='columns', thresh=3)
                    
                    print(df)
                    

                    使用 thresh 参数,您可以声明 DataFrame 中所有列的 NaN 值的最大计数。

                    代码输出:

                         a    b
                    0  1.0  1.0
                    1  2.0  2.0
                    2  3.0  NaN
                    3  4.0  4.0
                    4  NaN  NaN
                    

                    【讨论】:

                      【解决方案12】:

                      https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.count.html#pandas.Series.count

                      pandas.Series.count
                      Series.count(level=None)[source]
                      

                      返回系列中非 NA/null 观测值的数量

                      【讨论】:

                      • 问题是关于 NA/null 值的数量,而不是相反。
                      【解决方案13】:

                      请使用下面的特定列数

                      dataframe.columnName.isnull().sum()
                      

                      【讨论】:

                        【解决方案14】:

                        让我们假设df 是一个熊猫数据框。

                        那么,

                        df.isnull().sum(axis = 0)
                        

                        这将在每列中给出 NaN 值的数量。

                        如果需要,每行中的 NaN 值,

                        df.isnull().sum(axis = 1)
                        

                        【讨论】:

                          【解决方案15】:

                          计数零:

                          df[df == 0].count(axis=0)
                          

                          计算 NaN:

                          df.isnull().sum()
                          

                          df.isna().sum()
                          

                          【讨论】:

                            【解决方案16】:
                            import numpy as np
                            import pandas as pd
                            
                            raw_data = {'first_name': ['Jason', np.nan, 'Tina', 'Jake', 'Amy'], 
                                    'last_name': ['Miller', np.nan, np.nan, 'Milner', 'Cooze'], 
                                    'age': [22, np.nan, 23, 24, 25], 
                                    'sex': ['m', np.nan, 'f', 'm', 'f'], 
                                    'Test1_Score': [4, np.nan, 0, 0, 0],
                                    'Test2_Score': [25, np.nan, np.nan, 0, 0]}
                            results = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'sex', 'Test1_Score', 'Test2_Score'])
                            

                            results 
                            '''
                              first_name last_name   age  sex  Test1_Score  Test2_Score
                            0      Jason    Miller  22.0    m          4.0         25.0
                            1        NaN       NaN   NaN  NaN          NaN          NaN
                            2       Tina       NaN  23.0    f          0.0          NaN
                            3       Jake    Milner  24.0    m          0.0          0.0
                            4        Amy     Cooze  25.0    f          0.0          0.0
                            '''
                            

                            您可以使用以下函数,它将在 Dataframe 中为您提供输出

                            • 零值
                            • 缺失值
                            • 占总价值的百分比
                            • 总缺失值为零
                            • % 总零缺失值
                            • 数据类型

                            只需复制并粘贴以下函数并通过传递您的 pandas Dataframe 来调用它

                            def missing_zero_values_table(df):
                                    zero_val = (df == 0.00).astype(int).sum(axis=0)
                                    mis_val = df.isnull().sum()
                                    mis_val_percent = 100 * df.isnull().sum() / len(df)
                                    mz_table = pd.concat([zero_val, mis_val, mis_val_percent], axis=1)
                                    mz_table = mz_table.rename(
                                    columns = {0 : 'Zero Values', 1 : 'Missing Values', 2 : '% of Total Values'})
                                    mz_table['Total Zero Missing Values'] = mz_table['Zero Values'] + mz_table['Missing Values']
                                    mz_table['% Total Zero Missing Values'] = 100 * mz_table['Total Zero Missing Values'] / len(df)
                                    mz_table['Data Type'] = df.dtypes
                                    mz_table = mz_table[
                                        mz_table.iloc[:,1] != 0].sort_values(
                                    '% of Total Values', ascending=False).round(1)
                                    print ("Your selected dataframe has " + str(df.shape[1]) + " columns and " + str(df.shape[0]) + " Rows.\n"      
                                        "There are " + str(mz_table.shape[0]) +
                                          " columns that have missing values.")
                            #         mz_table.to_excel('D:/sampledata/missing_and_zero_values.xlsx', freeze_panes=(1,0), index = False)
                                    return mz_table
                            
                            missing_zero_values_table(results)
                            

                            输出

                            Your selected dataframe has 6 columns and 5 Rows.
                            There are 6 columns that have missing values.
                            
                                         Zero Values  Missing Values  % of Total Values  Total Zero Missing Values  % Total Zero Missing Values Data Type
                            last_name              0               2               40.0                          2                         40.0    object
                            Test2_Score            2               2               40.0                          4                         80.0   float64
                            first_name             0               1               20.0                          1                         20.0    object
                            age                    0               1               20.0                          1                         20.0   float64
                            sex                    0               1               20.0                          1                         20.0    object
                            Test1_Score            3               1               20.0                          4                         80.0   float64
                            

                            如果你想保持简单,那么你可以使用下面的函数来获取 % 中的缺失值

                            def missing(dff):
                                print (round((dff.isnull().sum() * 100/ len(dff)),2).sort_values(ascending=False))
                            
                            
                            missing(results)
                            '''
                            Test2_Score    40.0
                            last_name      40.0
                            Test1_Score    20.0
                            sex            20.0
                            age            20.0
                            first_name     20.0
                            dtype: float64
                            '''
                            

                            【讨论】:

                              【解决方案17】:

                              另一个尚未建议的简单选项(仅计算 NaN)是在形状中添加以返回带有 NaN 的行数。

                              df[df['col_name'].isnull()]['col_name'].shape
                              

                              【讨论】:

                                【解决方案18】:

                                假设您想在名为 review 的数据框中获取称为价格的列(系列)中的缺失值 (NaN) 的数量

                                #import the dataframe
                                import pandas as pd
                                
                                reviews = pd.read_csv("../input/wine-reviews/winemag-data-130k-v2.csv", index_col=0)
                                

                                要获取缺失值,以n_missing_prices为变量,很简单

                                n_missing_prices = sum(reviews.price.isnull())
                                print(n_missing_prices)
                                

                                sum 是这里的关键方法,在我意识到 sum 是在这种情况下使用的正确方法之前尝试使用 count

                                【讨论】:

                                  【解决方案19】:

                                  2017 年 7 月有一篇不错的 Dzone 文章详细介绍了总结 NaN 值的各种方法。看看here

                                  我引用的文章通过以下方式提供了额外的价值:(1) 展示了一种计算和显示每一列的 NaN 计数的方法,以便人们可以轻松地决定是否丢弃这些列;(2) 展示一种选择方法那些具有 NaN 的特定行,以便它们可以被选择性地丢弃或估算。

                                  这是一个演示该方法实用性的快速示例 - 只有几列可能它的用处并不明显,但我发现它对更大的数据框有帮助。

                                  import pandas as pd
                                  import numpy as np
                                  
                                  # example DataFrame
                                  df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})
                                  
                                  # Check whether there are null values in columns
                                  null_columns = df.columns[df.isnull().any()]
                                  print(df[null_columns].isnull().sum())
                                  
                                  # One can follow along further per the cited article
                                  

                                  【讨论】:

                                    【解决方案20】:

                                    如果您需要获取由 groupby 提取的不同组的非 NA(非无)和 NA(无)计数:

                                    gdf = df.groupby(['ColumnToGroupBy'])
                                    
                                    def countna(x):
                                        return (x.isna()).sum()
                                    
                                    gdf.agg(['count', countna, 'size'])
                                    

                                    这将返回非 NA、NA 和每组条目总数。

                                    【讨论】:

                                      【解决方案21】:

                                      您可以使用isna() 方法(或别名isnull(),它也与旧版pandas

                                      In [1]: s = pd.Series([1,2,3, np.nan, np.nan])
                                      
                                      In [4]: s.isna().sum()   # or s.isnull().sum() for older pandas versions
                                      Out[4]: 2
                                      

                                      对于多个列,它也适用:

                                      In [5]: df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})
                                      
                                      In [6]: df.isna().sum()
                                      Out[6]:
                                      a    1
                                      b    2
                                      dtype: int64
                                      

                                      【讨论】:

                                      • 如果你想要整个df中的nans总数,你可以使用df.isnull().sum().sum()
                                      • 获取 colsums,.sum(axis=0),这是默认行为。要获得行和,.sum(axis=1)
                                      • @RockJake28 或df.isnull().values.sum()
                                      • df['column_name'].isna().sum() 如果有人想知道也可以使用。
                                      • "and then sum to count the NaN values",要理解这句话,有必要理解df.isna()产生布尔系列,其中True的个数是NaNdf.isna().sum() 的数量分别将 FalseTrue 替换为 0 和 1。因此这间接计算了 NaN,其中一个简单的 count 将只返回列的长度.
                                      【解决方案22】:
                                      import pandas as pd
                                      import numpy as np
                                      
                                      # example DataFrame
                                      df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})
                                      
                                      # count the NaNs in a column
                                      num_nan_a = df.loc[ (pd.isna(df['a'])) , 'a' ].shape[0]
                                      num_nan_b = df.loc[ (pd.isna(df['b'])) , 'b' ].shape[0]
                                      
                                      # summarize the num_nan_b
                                      print(df)
                                      print(' ')
                                      print(f"There are {num_nan_a} NaNs in column a")
                                      print(f"There are {num_nan_b} NaNs in column b")
                                      

                                      作为输出:

                                           a    b
                                      0  1.0  NaN
                                      1  2.0  1.0
                                      2  NaN  NaN
                                      
                                      There are 1 NaNs in column a
                                      There are 2 NaNs in column b
                                      

                                      【讨论】:

                                        【解决方案23】:

                                        这是按列计算Null 值的代码:

                                        df.isna().sum()
                                        

                                        【讨论】:

                                          【解决方案24】:
                                          df1.isnull().sum()
                                          

                                          这样就可以了。

                                          【讨论】:

                                            【解决方案25】:

                                            在我的代码中使用了@sushmit 提出的解决方案。

                                            同样的可能变化也可以是

                                            colNullCnt = []
                                            for z in range(len(df1.cols)):
                                                colNullCnt.append([df1.cols[z], sum(pd.isnull(trainPd[df1.cols[z]]))])
                                            

                                            这样做的好处是它从今以后返回 df 中每一列的结果。

                                            【讨论】:

                                              【解决方案26】:

                                              根据给出的答案和一些改进,这是我的方法

                                              def PercentageMissin(Dataset):
                                                  """this function will return the percentage of missing values in a dataset """
                                                  if isinstance(Dataset,pd.DataFrame):
                                                      adict={} #a dictionary conatin keys columns names and values percentage of missin value in the columns
                                                      for col in Dataset.columns:
                                                          adict[col]=(np.count_nonzero(Dataset[col].isnull())*100)/len(Dataset[col])
                                                      return pd.DataFrame(adict,index=['% of missing'],columns=adict.keys())
                                                  else:
                                                      raise TypeError("can only be used with panda dataframe")
                                              

                                              【讨论】:

                                              • 我更喜欢df.apply(lambda x: x.value_counts(dropna=False)[np.nan]/x.size*100)
                                              【解决方案27】:

                                              您可以使用 value_counts 方法并打印 np.nan 的值

                                              s.value_counts(dropna = False)[np.nan]
                                              

                                              【讨论】:

                                              • 不错!如果您想同时计算 NaN 和非 NaN,这个是最有用的。 s.value_counts(dropna = False)
                                              【解决方案28】:

                                              如果它只是在 pandas 列中计算 nan 值是一种快速方法

                                              import pandas as pd
                                              ## df1 as an example data frame 
                                              ## col1 name of column for which you want to calculate the nan values
                                              sum(pd.isnull(df1['col1']))
                                              

                                              【讨论】:

                                              • sushmit,如果你有很多列,这种方式不是很快。在这种情况下,您必须复制并粘贴/键入每个列名,然后重新执行代码。
                                              【解决方案29】:

                                              如果你使用的是 Jupyter Notebook,怎么样....

                                               %%timeit
                                               df.isnull().any().any()
                                              

                                               %timeit 
                                               df.isnull().values.sum()
                                              

                                              或者,数据中是否有任何 NaN,如果有,在哪里?

                                               df.isnull().any()
                                              

                                              【讨论】:

                                                【解决方案30】:

                                                自 pandas 0.14.1 以来,我的建议 here 在 value_counts 方法中有一个关键字参数已经实现:

                                                import pandas as pd
                                                df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})
                                                for col in df:
                                                    print df[col].value_counts(dropna=False)
                                                
                                                2     1
                                                 1     1
                                                NaN    1
                                                dtype: int64
                                                NaN    2
                                                 1     1
                                                dtype: int64
                                                

                                                【讨论】:

                                                • 迄今为止的最佳答案,它还允许计算其他值类型。
                                                猜你喜欢
                                                • 2016-04-04
                                                • 2016-10-24
                                                • 2022-01-07
                                                • 1970-01-01
                                                • 1970-01-01
                                                • 2019-08-01
                                                • 1970-01-01
                                                相关资源
                                                最近更新 更多