如何替换数据框列中的NaN值

632

我有一个如下的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

当我尝试对Amount列应用函数时,出现以下错误:

ValueError: cannot convert float NaN to integer

我尝试使用Math Module中的.isnan函数进行应用 我尝试使用pandas .replace属性 我尝试过pandas 0.9中的.sparse数据属性 我还在一个函数中尝试了NaN == NaN语句 我还查看了这篇文章如何在R数据框中将NA值替换为零?,同时查看了其他一些文章。 我尝试的所有方法都没有起作用或无法识别NaN。 任何提示或解决方案都将不胜感激。


2
唯一的问题是,如果你正在应用 df.fill.na() 函数的数据框被重新采样或通过 loc 函数进行了切片,那么该函数将无法正常工作。 - Prince Agarwal
18个回答

974

我相信DataFrame.fillna()会为您完成此操作。

有关数据帧(DataFrame)序列(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)

1
df[1] 是原始 DataFrame 的视图而不是副本,这个有保证吗?显然,如果极少数情况下它是一个副本,那将会导致一个非常棘手的 bug。在 pandas 文档中有明确的说明吗? - max
@max 请看这个链接,可能会解决你的问题:https://dev59.com/qGAg5IYBdhLWcg3ws8ro - Aman
1
为什么这对我不起作用?请参见:https://dev59.com/hlkS5IYBdhLWcg3wzJP3 - Stefan Falk
1
最后一个例子会抛出SettingWithCopyWarning警告。 - Sip
1
@Farrukh Faizy的回答确实是fillna()设计用于处理特定列的方式。也许将第二个解决方案替换为他的解决方案,因为这样你的答案总是会排在前面? :) - johnDanger
显示剩余4条评论

193

不能保证切片操作返回的是视图或者拷贝。你可以使用

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

17
刚刚发现了“inplace=True”存在的问题。这个答案避免了这个问题,我认为它是提出的最简洁的解决方案。 - TimCera

66

您可以使用replace函数将NaN替换为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)

1
它只会替换 NaN 吗?还是也会替换 NA 或类似 df.fillna(0) 中的 NaN 值?我正在寻找仅替换 NaN 值而不是 NA 值的解决方案。 - Shyam Bhimani
1
@ShyamBhimani 它应该仅替换 NaN,即 np.isnan 为 True 的值。 - Anton Protopopov

31

以下代码对我有用。

import pandas

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

df = df.fillna(0)

一行代码df = pandas.read_csv('somefile.txt').fillna(0) - Siraj Alam

29

我只是想提供一些更新/特殊情况,因为看起来人们仍然在这里寻找答案。 如果您正在使用多级索引或以其他方式使用索引切片器,则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!

如果有人发现这个方法在某些情况下无法工作,请在评论中发布,我一直在测试并查看源代码,它似乎至少解决了我的多索引切片问题。


14

您也可以使用字典来填充DataFrame中特定列的NaN值,而不是用某个单一值填充整个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问题的预期解决方案。 - johnDanger

11

填充缺失值的简易方法:

填充字符串列:当字符串列存在缺失值和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)

9

将所有的NaN替换为0

df = df.fillna(0)

9

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

在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)

7

在 pandas 中替换缺失值

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

如果 inplace = False,则不会更新数据框(dataframe),而是返回已修改的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接