Pandas:ValueError:无法将浮点 NaN 转换为整数

Posted

技术标签:

【中文标题】Pandas:ValueError:无法将浮点 NaN 转换为整数【英文标题】:Pandas: ValueError: cannot convert float NaN to integer 【发布时间】:2018-04-30 04:51:06 【问题描述】:

我得到 ValueError: cannot convert float NaN to integer 如下:

df = pandas.read_csv('zoom11.csv')
df[['x']] = df[['x']].astype(int)
“x”显然是 csv 文件中的一列,但我无法在文件中发现任何 float NaN,并且不明白这是什么意思。 当我将该列读取为字符串时,它的值类似于 -1,0,1,...2000,在我看来都是非常好的 int 数字。 当我将该列读取为浮点数时,可以加载它。然后它显示值为 -1.0,0.0 等,仍然没有任何 NaN-s 我尝试使用 error_bad_lines = False 和 read_csv 中的 dtype 参数无济于事。它只是取消加载相同的异常。 文件不小(10+ M 行),所以无法手动检查,当我提取一个小的标题部分时,没有错误,但它发生在完整文件中。所以它是文件中的东西,但无法检测到什么。 从逻辑上讲,csv 不应该有缺失值,但即使有一些垃圾,我也可以跳过这些行。或者至少可以识别它们,但我看不到扫描文件并报告转换错误的方法。

更新:使用 cmets/answers 中的提示我得到了我的数据:

# x contained NaN
df = df[~df['x'].isnull()]

# Y contained some other garbage, so null check was not enough
df = df[df['y'].str.isnumeric()]

# final conversion now worked
df[['x']] = df[['x']].astype(int)
df[['y']] = df[['y']].astype(int)

【问题讨论】:

试试看df[df['x'].isnull()] 你需要弄清楚你想用任何 NaN 做什么,然后去做。 感谢@jezrael,现在 df[df['x'].isnull()] 确实用“NaN”标识了一行,我可以删除它!现在有了另一个类似的领域 - 这似乎有一些其他的垃圾不是 int。是否有通用的方法来查找无法转换为给定数据类型的行,以便我可以识别它们并将它们全部丢弃? 使用 pd.to_numericerrors = coerce 而不是 astype int 然后 fillna 随便你。 在 v0.24 中,pandas 引入了 Nullable 整数类型,它支持带有 NaN 的整数列。请参阅this answer 了解更多信息。 【参考方案1】:

要识别NaN 值,请使用boolean indexing

print(df[df['x'].isnull()])

然后要删除所有非数字值,请使用 to_numeric 和参数 errors='coerce' - 将非数字值替换为 NaNs:

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

对于删除NaNs 列中x 的所有行,请使用dropna

df = df.dropna(subset=['x'])

上次将值转换为ints:

df['x'] = df['x'].astype(int)

【讨论】:

谢谢,没关系。我用我的台词更新了我的问题。我不明白的最后一件事是为什么我得到 False 的负数:'-1'.isnumeric()?我的 x 和 y >=0 的数据没有问题,但一般问题仍然存在,因为我在官方文档中没有看到它。 您可能会看到,因为 python 将 '-1' 解释为字符串,而不是数字【参考方案2】:

ValueError: 无法将浮点 NaN 转换为整数

从 v0.24 开始,您实际上可以。 Pandas 引入了Nullable Integer Data Types,它允许整数与 NaN 共存。

给定一系列带有缺失数据的整数,

s = pd.Series([1.0, 2.0, np.nan, 4.0])
s

0    1.0
1    2.0
2    NaN
3    4.0
dtype: float64

s.dtype
# dtype('float64')

您可以使用以下命令将其转换为可为空的 int 类型(从Int16Int32Int64 中选择一种),

s2 = s.astype('Int32') # note the 'I' is uppercase
s2

0      1
1      2
2    NaN
3      4
dtype: Int32

s2.dtype
# Int32Dtype()

您的专栏需要有整数才能进行演员表。其他任何事情都会引发 TypeError:

s = pd.Series([1.1, 2.0, np.nan, 4.0])

s.astype('Int32')
# TypeError: cannot safely cast non-equivalent float64 to int32

【讨论】:

我收到一条错误消息,提示 TypeError: object cannot be converted to an IntegerDtype 你知道这意味着什么吗?【参考方案3】:

此外,即使在最新版本的 pandas 中,如果列是 object 类型,您也必须先转换为 float,例如:

df['column_name'].astype(np.float).astype("Int32")

注意:出于某种原因,您必须先经过 numpy float,然后再到可为空的 Int32。

int 的大小(如果是 32 或 64)取决于您的变量,请注意,如果您的数字对于格式而言太大,您可能会失去一些精度。

【讨论】:

【参考方案4】:

我知道这个问题已经得到解答,但想在未来为任何人提供替代解决方案:

您可以使用.loc 仅按notnull() 的值对数据框进行子集化,然后仅将'x' 列子集化。取同一个向量,然后 apply(int) 到它。

如果 x 列是浮点数:

df.loc[df['x'].notnull(), 'x'] = df.loc[df['x'].notnull(), 'x'].apply(int)

【讨论】:

左边部分做了它应该做的,但在 df 中它保持格式为浮动。 (Python 3.6,熊猫 0.22)【参考方案5】:

如果您有空值,那么在进行数学运算时,如果您希望数据集不可更改,您将使用df[~df['x'].isnull()]df[['x']].astype(int) 解决此错误。

【讨论】:

以上是关于Pandas:ValueError:无法将浮点 NaN 转换为整数的主要内容,如果未能解决你的问题,请参考以下文章

无法将字符串转换为 pandas 中的浮点数(ValueError)

Pandas - ValueError:无法从重复的轴重新索引

Pandas 和 DateTime TypeError:无法将 TimedeltaIndex 与浮点类型进行比较

ValueError:groupby Pandas 中的“无法从重复的轴重新索引”

pandas ValueError:转换无法产生聚合结果

Pandas - 在数据框中附加字符串:ValueError:无法从重复的轴重新索引