NumPy或Pandas:将数组类型保持为整数,同时具有NaN值

时间:2012-07-18 18:30:03

标签: python numpy int pandas type-conversion

是否有一种首选的方法可以将numpy数组的数据类型固定为int(或int64或其他),同时仍然将内部元素列为{{1 }}?

特别是,我正在将内部数据结构转换为Pandas DataFrame。在我们的结构中,我们有整数类型的列仍然有NaN(但列的dtype是int)。如果我们将其设为DataFrame,它似乎将所有内容重新设置为float,但我们真的希望成为numpy.NaN

思想?

尝试过的事情:

我尝试使用pandas.DataFrame下的int函数,from_records(),但这没有帮助。我也尝试使用带有NaN fill_value的NumPy掩码数组,这也没有用。所有这些都导致列数据类型变为浮点数。

9 个答案:

答案 0 :(得分:94)

NaN无法存储在整数数组中。这是目前大熊猫的一个已知限制;我一直在等待NumPy中NA值的进展(类似于R中的NAs),但是在NumPy获得这些功能之前至少需要6个月到一年,似乎:

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(此功能已从Pandas版本0.24开始添加,但请注意它需要使用扩展名dtype Int64(大写),而不是默认的dtype int64(小写): https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support

答案 1 :(得分:38)

此功能已添加到熊猫(从0.24版开始): https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support

这时,它需要使用扩展名dtype Int64(大写),而不是默认的dtype int64(小写)。

答案 2 :(得分:7)

如果性能不是主要问题,则可以存储字符串。

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

然后您可以根据需要与NaN混合。如果您确实希望使用整数,则可以使用-101234567890或其他专用值来表示NaN

你也可以暂时复制这些列:一个就像你一样,有浮动;另一个实验,有整数或字符串。然后在每个合理的位置插入asserts,检查两者是否同步。经过充分的测试,你可以放下花车。

答案 3 :(得分:3)

这不是所有病例的解决方案,但我的(基因组坐标)我已经使用0作为NaN

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

这至少允许使用正确的“原生”列类型,减法,比较等操作按预期工作

答案 4 :(得分:2)

Pandas v0.24 +

v0.24或更高版本将支持整数系列中的NaN。 v0.24“新增功能”部分中有information on this,而Nullable Integer Data Type下有更多详细信息。

Pandas v0.23和更早版本

通常,最好在可能的情况下使用float系列,即使由于包含int值而将该系列从float转换为NaN也是如此。这样可以进行基于矢量的基于NumPy的计算,否则将处理Python级别的循环。

文档确实suggest:“一种可能性是改用dtype=object数组。”例如:

s = pd.Series([1, 2, 3, np.nan])

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object

出于装饰性原因,例如输出到文件中,此 可能更好。

Pandas v0.23和更早版本:背景

NaN is considered a floatdocs currently (as of v0.23)指定将整数序列提升为float的原因:

  

在缺乏高性能NA支持的情况下,NumPy已内置   从头开始,主要的伤亡是代表   整数数组中的NA。

     

这种权衡主要是出于内存和性能方面的考虑,并且   还可以使生成的序列继续为“数字”。

由于包含NaN,因此文档也provide rules也要上传:

Typeclass   Promotion dtype for storing NAs
floating    no change
object      no change
integer     cast to float64
boolean     cast to object

答案 5 :(得分:1)

这是可能的,因为pandas v 0.24.0

pandas 0.24.x release notes Quote:“ Pandas已具备保留具有缺失值的整数dtypes的功能。

答案 6 :(得分:0)

只需添加一下,以防您尝试将float(1.143)向量转换为将NA转换为新的'Int64'dtype的整数(1)会出现错误。为了解决这个问题,您必须将数字四舍五入,然后执行“ .astype('Int64')”

IconData

我的用例是我有一个浮点数系列,我想四舍五入为整数,但是当您执行.round()时,数字末尾仍为'* .0',因此您可以从通过转换为int结束。

答案 7 :(得分:0)

如果文本数据中有空格,则通常为整数的列将被转换为float64 dtype,因为int64 dtype无法处理null。如果您加载多个文件,其中一些带有空白(最终将以float64而其他文件则将以int64结束

),则这可能会导致架构不一致。

此代码将尝试将任何数字类型的列转换为Int64(而不是int64),因为Int64可以处理空值

import pandas as pd
import numpy as np

#show datatypes before transformation
mydf.dtypes

for c in mydf.select_dtypes(np.number).columns:
    try:
        mydf[c] = mydf[c].astype('Int64')
        print('casted {} as Int64'.format(c))
    except:
        print('could not cast {} to Int64'.format(c))

#show datatypes after transformation
mydf.dtypes

答案 8 :(得分:0)

Pandas v1.00 + 的新功能

您不再(并且不能)再使用 numpy.nan。 现在你有 pandas.NA

请阅读:https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html

<块引用>

IntegerArray 目前处于实验阶段。它的 API 或实现可能 无预警更改。

在 1.0.0 版更改:现在使用 pandas.NA 作为缺失值 而不是 numpy.nan。

在处理缺失数据中,我们看到 Pandas 主要使用 NaN 表示缺失的数据。因为 NaN 是一个浮点数,这会强制一个数组 具有任何缺失值的整数成为浮点数。在一些 在这种情况下,这可能无关紧要。但是如果你的整数列是,说, 一个标识符,转换为浮动可能有问题。一些整数 甚至不能表示为浮点数。