【问题标题】:How to replace all non-numeric entries with NaN in a pandas dataframe?如何在熊猫数据框中用 NaN 替换所有非数字条目?
【发布时间】:2017-01-30 14:39:32
【问题描述】:

我有各种 csv 文件,并将它们作为 DataFrame 导入。问题是许多文件对缺失值使用不同的符号。有些人使用 nan,其他人使用 NaN、ND、None、missing 等,或者只是将条目留空。有没有办法用 np.nan 替换所有这些值?换句话说,数据帧中的任何非数字值都会变成 np.nan。谢谢你的帮助。

【问题讨论】:

  • read_csv 接受 na_value arg,您可以传递可能的 na 值列表,否则您可以在 df 上调用 to_numeric(errors='coerce')
  • 查看相关:stackoverflow.com/questions/15891038/… 以了解后处理选项
  • 感谢 EdChym,这很有帮助。
  • 基本上,如果您知道所有可能的 nan 值,则使用 read_csv 如果它们未知但您知道有些是无效的,则使用后处理选项

标签: python pandas


【解决方案1】:

我发现我认为是一种相对优雅但也很健壮的方法:

def isnumber(x):
    try:
        float(x)
        return True
    except:
        return False

df[df.applymap(isnumber)]

如果不清楚:您定义一个返回 True 的函数,前提是您拥有的任何输入都可以转换为浮点数。然后,您使用该布尔数据框过滤 df,它会自动将 NaN 分配给您未过滤的单元格。

我尝试的另一个解决方案是将isnumber 定义为

import number
def isnumber(x):
    return isinstance(x, number.Number)

但我不太喜欢这种方法的是,您可能会不小心将数字作为字符串,因此您会错误地将它们过滤掉。这也是一个偷偷摸摸的错误,看到数据框显示字符串"99" 与数字99 相同。

编辑:

在您的情况下,您可能仍然需要在过滤后使用df = df.applymap(float),因为float 适用于'nan' 的所有不同大小写,但在您明确转换它们之前,它们仍将被视为数据框中的字符串。

【讨论】:

  • 感谢优雅的解决方案
【解决方案2】:

在读取时替换非数字条目,更简单(更安全)的方式

TL;DR:为未正确转换的列设置数据类型,并提供 na_values 列表

# Create a custom list of values I want to cast to NaN, and explicitly 
#   define the data types of columns:
na_values = ['None', '(S)', 'S']
last_names = pd.read_csv('names_2010_census.csv', dtype={'pctapi': np.float64}, na_values=na_values)

更长的解释

我认为处理杂乱数据时的最佳做法是:

  • 为未正确推断数据类型的列向 pandas 提供数据类型。
  • 明确定义应转换为 NaN 的值列表。

这很容易做到。

Pandas read_csv 有一个值列表,它会在解析数据时查找并自动转换为 NaN(有关列表,请参见 read_csvdocumentation)。您可以使用 na_values 参数扩展此列表,并且可以告诉 pandas 如何使用 dtypes 参数转换特定列。

在上面的示例中,pctapi 是由于 NaN 值而被强制转换为对象类型而不是 float64 的列的名称。因此,我强制 pandas 转换为 float64 并为 read_csv 函数提供要转换为 NaN 的值列表。

我遵循的过程

由于数据科学通常完全是关于过程的,我想我描述了我用来创建 na_values 列表并使用数据集调试此问题的步骤。

第一步:尝试导入数据,让 pandas 推断数据类型。检查数据类型是否符合预期。如果他们是 = 继续前进。

在上面的示例中,Pandas 在大约一半的列上是正确的。但是,我希望“count”字段下方列出的所有列都是 float64 类型。我们需要解决这个问题。

步骤 2:如果数据类型不符合预期,则使用 dtypes 参数显式设置读取时的数据类型。默认情况下,这将在无法强制转换的值上引发错误。

# note: the dtypes dictionary specifying types. pandas will attempt to infer
#   the type of any column name that's not listed
last_names = pd.read_csv('names_2010_census.csv', dtype={'pctwhite': np.float64})

这是我在运行上述代码时收到的错误消息:

第 3 步:创建一个 pandas 无法转换的值的显式列表,并在读取时将它们转换为 NaN。

从错误消息中,我可以看到 pandas 无法转换 (S) 的值。我将此添加到我的 na_values 列表中:

# note the new na_values argument provided to read_csv
last_names = pd.read_csv('names_2010_census.csv', dtype={'pctwhite': np.float64}, na_values=['(S)'])

最后,我重复步骤 2 和 3,直到获得 dtype 映射和 na_values 的完整列表。

如果您正在从事业余爱好者项目,则此方法可能超出您的需要,您可能希望改用 u/instant 的答案。但是,如果您在生产系统或团队中工作,那么花 10 分钟来正确投射列是非常值得的。

【讨论】:

  • 如果要转换为 NaN 的值没有单个值或几个值,而是具有相似的形式,该怎么办?例如,如果我希望一列是数字,但它的某些条目是不同的字符串,我该如何删除它们?
猜你喜欢
  • 2018-03-25
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2019-05-09
  • 2021-05-25
  • 2015-10-12
  • 2014-09-25
相关资源
最近更新 更多