【问题标题】:How to replace NaN values by Zeroes in a column of a Pandas Dataframe?如何在 Pandas 数据框的列中用零替换 NaN 值?
【发布时间】:2012-10-29 01:04:16
【问题描述】:

我有一个如下的 Pandas 数据框:

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

当我尝试将函数应用于金额列时,我收到以下错误:

ValueError: cannot convert float NaN to integer

我尝试使用数学模块中的 .isnan 应用函数 我已经尝试过 pandas .replace 属性 我尝试了 pandas 0.9 中的 .sparse 数据属性 我也尝试过 if NaN == NaN 函数中的语句。 我还查看了这篇文章How do I replace NA values with zeros in an R dataframe?,同时查看了其他一些文章。 我尝试过的所有方法都不起作用或无法识别 NaN。 任何提示或解决方案将不胜感激。

【问题讨论】:

  • 唯一的问题是 df.fill.na() 如果您应用它的数据框被重新采样或已通过 loc 函数切片,则它不起作用

标签: python pandas dataframe nan


【解决方案1】:

我相信DataFrame.fillna() 会为你做到这一点。

a dataframea Series 的文档链接。

例子:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

要仅将 NaN 填充在一列中,请仅选择该列。在这种情况下,我使用 inplace=True 来实际更改 df 的内容。

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

编辑:

要避免SettingWithCopyWarning,请使用内置的特定于列的功能:

df.fillna({1:0}, inplace=True)

【讨论】:

  • 是否保证df[1] 是视图而不是原始DF 的副本?很明显,如果在极少数情况下它是副本,那将导致一个超级麻烦的错误。 pandas 文档中有明确的说明吗?
  • @max 看到这个,可能会解决你的问题:stackoverflow.com/questions/23296282/…
  • 最后一个例子抛出一个 SettingWithCopyWarning
  • @Farrukh Faizy 的回答确实是 fillna() 旨在处理特定列的方式。也许用他替换第二个解决方案,因为您的答案将永远是最重要的? :)
【解决方案2】:

不保证切片返回视图或副本。你可以这样做

df['column'] = df['column'].fillna(value)

【讨论】:

  • 刚刚发现“inplace=True”问题。这个答案避免了这个问题,我认为是最干净的解决方案。
【解决方案3】:

您可以使用replaceNaN 更改为0

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

【讨论】:

  • 它只会替换 NaN 吗?或者它也将替换NANaN 的值,如df.fillna(0)?我正在寻找仅替换存在 NaN 而不是 NA 的值的解决方案
  • @ShyamBhimani 它应该只替换 NaNnp.isnan 为 True 的值
【解决方案4】:

下面的代码对我有用。

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

【讨论】:

    【解决方案5】:

    我只是想提供一些更新/特殊情况,因为看起来人们仍然来到这里。如果您使用多索引或以其他方式使用索引切片器,则 inplace=True 选项可能不足以更新您选择的切片。例如,在 2x2 级别的多索引中,这不会更改任何值(从 pandas 0.15 开始):

    idx = pd.IndexSlice
    df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)
    

    “问题”是链接破坏了 fillna 更新原始数据帧的能力。我将“问题”放在引号中,因为设计决策有充分的理由导致在某些情况下不通过这些链进行解释。此外,这是一个复杂的示例(尽管我确实遇到过),但根据您的切片方式,这可能适用于较少级别的索引。

    解决方法是DataFrame.update:

    df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))
    

    这是一行,读起来相当好(有点),消除了中间变量或循环的任何不必要的混乱,同时允许您将 fillna 应用于您喜欢的任何多级切片!

    如果有人能找到这不起作用的地方,请在 cmets 中发布,我一直在搞乱它并查看源代码,它似乎至少解决了我的多索引切片问题。

    【讨论】:

      【解决方案6】:

      您还可以使用字典来填充 DataFrame 中特定列的 NaN 值,而不是用一些 oneValue 填充所有 DF。

      import pandas as pd
      
      df = pd.read_excel('example.xlsx')
      df.fillna( {
              'column1': 'Write your values here',
              'column2': 'Write your values here',
              'column3': 'Write your values here',
              'column4': 'Write your values here',
              .
              .
              .
              'column-n': 'Write your values here'} , inplace=True)
      

      【讨论】:

      • 这是针对 OP 问题的开发人员意图解决方案。
      【解决方案7】:

      填充缺失值的简单方法:-

      填充 字符串列:当字符串列有缺失值和NaN值时。

      df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)
      

      填充 数值列:当数值列有缺失值和NaN值时。

      df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)
      

      用零填充 NaN:

      df['column name'].fillna(0, inplace = True)
      

      【讨论】:

        【解决方案8】:

        替换 pandas 中的 na 值

        df['column_name'].fillna(value_to_be_replaced,inplace=True)
        

        如果inplace = False,它将返回修改后的值,而不是更新 df(数据帧)。

        【讨论】:

          【解决方案9】:

          考虑到上表中的特定列Amount 是整数类型。以下将是一个解决方案:

          df['Amount'] = df.Amount.fillna(0).astype(int)
          

          同样,您可以使用floatstr 等各种数据类型填充它。

          特别是,我会考虑使用数据类型来比较同一列的各种值。

          【讨论】:

            【解决方案10】:

            用不同的方式替换不同列中的nan:

               replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
               df.fillna(value=replacement)
            

            【讨论】:

              【解决方案11】:

              将所有 nan 替换为 0

              df = df.fillna(0)
              

              【讨论】:

                【解决方案12】:

                如果您要将其转换为 pandas 数据框,您也可以使用 fillna 完成此操作。

                import numpy as np
                df=np.array([[1,2,3, np.nan]])
                
                import pandas as pd
                df=pd.DataFrame(df)
                df.fillna(0)
                

                这将返回以下内容:

                     0    1    2   3
                0  1.0  2.0  3.0 NaN
                >>> df.fillna(0)
                     0    1    2    3
                0  1.0  2.0  3.0  0.0
                

                【讨论】:

                  【解决方案13】:

                  主要有两种选择;如果仅使用数字替换(跨列)填充或填充缺失值 NaN / np.nan

                  df['Amount'].fillna(value=None, method= ,axis=1,) 就足够了:

                  来自文档:

                  值:标量、字典、系列或数据帧 用于填充孔的值(例如 0),或者 dict/Series/DataFrame 的值指定使用哪个值 每个索引(对于 Series)或列(对于 DataFrame)。 (值不 在 dict/Series/DataFrame 中不会被填充)。这个值不能 成为一个列表。

                  这意味着不再允许估算“字符串”或“常量”。

                  对于更专业的插补,请使用 SimpleImputer()

                  from sklearn.impute import SimpleImputer
                  si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
                  df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])
                  
                  

                  【讨论】:

                    【解决方案14】:

                    这对我有用,但没有人提到它。会不会有什么问题?

                    df.loc[df['column_name'].isnull(), 'column_name'] = 0
                    

                    【讨论】:

                    • 只有这对我有用:D,df.fillna(0) 没有用(没有任何错误)
                    【解决方案15】:

                    如果要为特定列填充 NaN,可以使用 loc:

                    d1 = {"Col1" : ['A', 'B', 'C'],
                         "fruits": ['Avocado', 'Banana', 'NaN']}
                    d1= pd.DataFrame(d1)
                    
                    output:
                    
                    Col1    fruits
                    0   A   Avocado
                    1   B   Banana
                    2   C   NaN
                    
                    
                    d1.loc[ d1.Col1=='C', 'fruits' ] =  'Carrot'
                    
                    
                    output:
                    
                    Col1    fruits
                    0   A   Avocado
                    1   B   Banana
                    2   C   Carrot
                    

                    【讨论】:

                      【解决方案16】:

                      已经有很多贡献了,但由于我是新来的,我仍然会提供意见。

                      有两种方法可以在 Pandas DataFrame 中用零替换 NaN 值:

                      1. fillna():函数使用指定的方法填充 NA/NaN 值。
                      2. replace():df.replace()一个简单的方法,用来替换字符串、正则表达式、列表、字典

                      例子:

                      #NaN with zero on all columns
                      df2 = df.fillna(0)
                      
                      
                      #Using the inplace=True keyword in a pandas method changes the default behaviour.
                          df.fillna(0, inplace = True)
                      
                      # multiple columns appraoch
                      df[["Student", "ID"]] = df[["Student", "ID"]].fillna(0)
                      

                      最后是 replace() 方法:

                      df["Student"] = df["Student"].replace(np.nan, 0)
                      

                      【讨论】:

                        猜你喜欢
                        • 2013-08-11
                        • 2022-10-05
                        • 2020-03-25
                        • 1970-01-01
                        • 2016-10-16
                        • 2017-12-05
                        相关资源
                        最近更新 更多