如何在熊猫数据框中设置 NaN 单元格

我想用 NaN 替换数据框架列中的坏值。

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)


df[df.y == 'N/A']['y'] = np.nan

但是,最后一行失败并抛出一个警告,因为它正在处理 df的副本。那么,正确的处理方法是什么?我已经看到了许多解决方案与 ilocix,但在这里,我需要使用一个布尔条件。

342049 次浏览

使用 replace:

In [106]:
df.replace('N/A',np.NaN)


Out[106]:
x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

您正在尝试的是所谓的链索引: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

你可以使用 loc来确保你操作的是原来的 dF:

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df


Out[108]:
x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

你可使用:

df['y'] = df['y'].replace({'N/A': np.nan})

还要注意 replaceinplace参数。你可以这样做:

df.replace({'N/A': np.nan}, inplace=True)

这将在不创建副本的情况下替换 df 中的所有实例。

类似地,如果遇到其他类型的未知值,如空字符串或 Nothing 值:

df['y'] = df['y'].replace({'': np.nan})


df['y'] = df['y'].replace({None: np.nan})

参考资料: 最新的熊猫-更换

虽然使用 replace似乎可以解决这个问题,但我想提出一个替代方案。在列中混合使用数值和一些字符串值时出现的问题是,不能用 np.nan 替换字符串,而是要使整个列适当。我敢打赌,最初的列很可能是一个对象类型

Name: y, dtype: object

您真正需要的是使其成为一个数值列(它将具有适当的类型,并且速度会更快) ,所有非数值都由 NaN 替换。

因此,好的转换代码应该是

pd.to_numeric(df['y'], errors='coerce')

指定 errors='coerce'强制将无法解析为数值的字符串转换为 NaN

Name: y, dtype: float64

你可以试试这些片段。

In [16]:mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
In [17]:df=pd.DataFrame(mydata)


In [18]:df.y[df.y=="N/A"]=np.nan


Out[19]:df
x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
df.loc[df.y == 'N/A',['y']] = np.nan

这能解决你的问题。使用 double [] ,您将处理 DataFrame 的副本。您必须在一个调用中指定确切的位置才能修改它。

从熊猫1.0.0开始,您不再需要使用 numpy 在数据框中创建 null 值。相反,您可以只使用 Pandas.NA (它的类型是 Pandas._ libs)。NAType) ,因此它在数据框架内将被视为 null,但在数据框架上下文之外不会被视为 null。

要直接在 DataFrame中替换 value,请使用 inplace参数。

df.replace('columnvalue', np.NaN, inplace=True)

上面这里的大多数答复都需要导入一个外部模块: import numpy as np

熊猫本身有一个内置的解决方案: pd.NA,这样使用:

df.replace('N/A', pd.NA)

你可以使用 wheremask:

df = df.where(df != 'N/A')

或者

df = df.mask(df == 'N/A')