将包含NaN的Pandas列转换为dtype`int`

Zhu*_*arb 132 python pandas na

我将.csv文件中的数据读取到Pandas数据帧,如下所示.对于其中一列,即id我想将列类型指定为int.问题是id系列缺少/空值.

当我尝试id在读取.csv时将列转换为整数时,我得到:

df= pd.read_csv("data.csv", dtype={'id': int}) 
error: Integer column has NA values
Run Code Online (Sandbox Code Playgroud)

或者,我尝试在阅读后转换列类型,如下所示,但这次我得到:

df= pd.read_csv("data.csv") 
df[['id']] = df[['id']].astype(int)
error: Cannot convert NA to integer
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题?

And*_*den 137

在整数列中缺少NaN rep是熊猫"陷阱".

通常的解决方法是简单地使用浮动.

  • 在v0.24中,您现在可以执行df = df.astype(pd.Int32Dtype())(以转换整个dataFrame,或者)`df ['col'] = df ['col']。astype(pd .Int32Dtype())`。其他可接受的可为空的整数类型为pd.Int16Dtype和pdInt64Dtype。选择你的毒药。 (12认同)
  • 除了像花车那样对待它们之外还有其他的解决方法吗? (9认同)
  • @ jsc123你可以使用对象dtype.这附带一个小的健康警告,但大多数情况下效果很好. (3认同)
  • 它是 NaN 值,但 isnan 检查根本不起作用:( (2认同)

jez*_*ael 44

在0.24。+版本中,pandas获得了保留缺少值的整数dtypes的功能。

可空整数数据类型

大熊猫可以使用来表示可能缺少值的整数数据arrays.IntegerArray。这是在熊猫中实现的扩展类型。它不是整数的默认dtype,因此不会进行推断。您必须将dtype明确传递给array()Series

arr = pd.array([1, 2, np.nan], dtype=pd.Int64Dtype())
pd.Series(arr)

0      1
1      2
2    NaN
dtype: Int64
Run Code Online (Sandbox Code Playgroud)

要将列转换为可为空的整数,请使用:

df['myCol'] = df['myCol'].astype('Int64')
Run Code Online (Sandbox Code Playgroud)

  • 请注意,dtype 必须是“Int64”而不是“int64”(第一个“i”必须大写) (34认同)
  • 这对某些人来说可能是显而易见的,但我认为仍然值得注意的是,您可以使用任何 Int (例如“Int16”、“Int32”),并且如果数据帧非常大以节省内存,则确实可能应该使用。 (7认同)
  • `df.myCol = df.myCol.astype('Int64')` 或 `df['myCol'] = df['myCol'].astype('Int64')` (4认同)
  • 我收到“类型错误:无法安全地将非等价的 float64 转换为 int64” (4认同)
  • 我喜欢这个答案。 (3认同)
  • 对于较新的熊猫版本,这是正确的答案。 (2认同)

hib*_*ado 31

我的用例是在加载到数据库表之前重新整理数据:

df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = df[col].astype(str)
df[col] = df[col].replace('-1', np.nan)
Run Code Online (Sandbox Code Playgroud)

删除NaNs,转换为int,转换为str然后重新插入NAN.

它不漂亮,但它完成了工作!

  • 仅当 col 还没有 -1 时才有效。不然数据会乱 (4认同)
  • OP 需要一列整数。将其转换为字符串不满足条件。 (3认同)
  • 我一直在费尽心思地尝试加载序列号,其中一些为空,其余的是浮点数,这救了我。 (2认同)

Abh*_*tia 15

无论您的 pandas 系列是object数据类型还是简单的float数据类型,以下方法都可以使用

df = pd.read_csv("data.csv") 
df['id'] = df['id'].astype(float).astype('Int64')
Run Code Online (Sandbox Code Playgroud)


mor*_*ork 8

现在可以创建一个包含 NaN 作为intdtype的 pandas 列,因为它现在正式添加到 pandas 0.24.0

pandas 0.24.x 发行说明 引用:“ Pandas 已经获得了保存缺失值的整数 dtypes 的能力


小智 7

从 Pandas 1.0.0 开始,您现在可以使用 pandas.NA 值。这不会强制缺少值的整数列为浮点数。

读取数据时,您所要做的就是:

df= pd.read_csv("data.csv", dtype={'id': 'Int64'})  
Run Code Online (Sandbox Code Playgroud)

请注意,“Int64”被引号括起来,并且 I 是大写的。这将 Panda 的“Int64”与 numpy 的 int64 区分开来。

附带说明一下,这也适用于 .astype()

df['id'] = df['id'].astype('Int64')
Run Code Online (Sandbox Code Playgroud)

如果您确实有浮动,您可能必须使用圆形。

df['id'] = df['id'].round().astype('Int64')
Run Code Online (Sandbox Code Playgroud)

此处的文档 https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html


jme*_*und 6

如果您绝对想在一列中组合整数和 NaN,您可以使用 'object' 数据类型:

df['col'] = (
    df['col'].fillna(0)
    .astype(int)
    .astype(object)
    .where(df['col'].notnull())
)
Run Code Online (Sandbox Code Playgroud)

这将用整数替换 NaN(与哪个无关),转换为 int,转换为对象,最后重新插入 NaN。


elo*_*age 5

.dropna()如果可以删除具有 NaN 值的行,则可以使用。

df = df.dropna(subset=['id'])
Run Code Online (Sandbox Code Playgroud)

或者,使用.fillna().astype()将 NaN 替换为值并将其转换为 int。

我在处理具有大整数的 CSV 文件时遇到了这个问题,而其中一些整数丢失了(NaN)。使用 float 作为类型不是一个选择,因为我可能会失去精度。

我的解决方案是使用 str 作为中间类型。然后您可以根据需要在代码中将字符串转换为 int。我将 NaN 替换为 0,但您可以选择任何值。

df = pd.read_csv(filename, dtype={'id':str})
df["id"] = df["id"].fillna("0").astype(int)
Run Code Online (Sandbox Code Playgroud)

为了便于说明,下面是浮点数如何失去精度的示例:

s = "12345678901234567890"
f = float(s)
i = int(f)
i2 = int(s)
print (f, i, i2)
Run Code Online (Sandbox Code Playgroud)

输出是:

1.2345678901234567e+19 12345678901234567168 12345678901234567890
Run Code Online (Sandbox Code Playgroud)


Kam*_*mil 5

几周前我遇到了一些离散功能的问题,这些功能被格式化为“对象”。这个解决方案似乎有效。

for col in discrete:
    df[col] = pd.to_numeric(df[col],errors='coerce').astype(pd.Int64Dtype())
Run Code Online (Sandbox Code Playgroud)