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

Python NumPy或Pandas:在具有NaN值时将数组类型保持为整数,python,numpy,int,pandas,type-conversion,Python,Numpy,Int,Pandas,Type Conversion,是否有一种首选方法可以将numpy数组的数据类型固定为int(或int64或其他任何类型),同时仍将数组中的元素列为numpy.NaN 特别是,我正在将内部数据结构转换为数据帧。在我们的结构中,整数类型的列仍然有NaN(但列的数据类型是int)。如果我们把它变成一个数据帧,它似乎会把所有的东西都改写成一个浮点,但我们真的希望变成int 想法 尝试过的事情: 我尝试使用pandas.DataFrame下的from_records()函数,使用强制\u float=False,但这没有帮助。我还尝试

是否有一种首选方法可以将
numpy
数组的数据类型固定为
int
(或
int64
或其他任何类型),同时仍将数组中的元素列为
numpy.NaN

特别是,我正在将内部数据结构转换为数据帧。在我们的结构中,整数类型的列仍然有NaN(但列的数据类型是int)。如果我们把它变成一个数据帧,它似乎会把所有的东西都改写成一个浮点,但我们真的希望变成
int

想法

尝试过的事情:


我尝试使用pandas.DataFrame下的
from_records()
函数,使用
强制\u float=False
,但这没有帮助。我还尝试使用NumPy掩码数组,使用NaN fill_值,这也不起作用。所有这些都导致列数据类型变为浮点。

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

(此功能是从pandas的0.24版开始添加的,但请注意,它需要使用扩展名dtype Int64(大写),而不是默认的dtype Int64(小写):
)

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

df.col = df.col.dropna().apply(lambda x: str(int(x)) )
然后,您可以将其与
NaN
任意混合。如果您确实想要整数,根据您的应用程序,您可以使用
-1
,或
0
,或
1234567890
,或其他一些专用值来表示
NaN


您还可以临时复制列:一个是带有浮点数的列;另一个是实验性的,带有int或string。然后在每个合理的位置插入
断言
,检查两者是否同步。经过足够的测试,你可以放开浮子

这不是所有情况下的解决方案,但我的(基因组坐标)使用0作为NaN

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

这至少允许使用适当的“本机”列类型,减法、比较等操作按预期工作

此功能已添加到pandas(从0.24版开始):

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

v0.24+ 在v0.24以上版本中将提供支持整数系列中的
NaN
的功能。在v0.24“新功能”部分中有,更多详细信息请参见

熊猫v0.23及更早版本 通常,如果可能,最好使用
float
序列,即使序列由于包含
NaN
值而从
int
向上转换为
float
。这将启用基于矢量化NumPy的计算,否则将处理Python级别的循环

文档会这样做:“一种可能是使用
dtype=object
数组代替。”例如:

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

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object
出于外观上的原因,例如输出到文件,这可能更可取

熊猫v0.23及更早版本:背景 。指定整数系列上溯到浮点的原因:

在NumPy中没有内置高性能NA支持的情况下 从一开始,主要的受害者就是代表的能力 整数阵列中的NAs

这种折衷主要是出于内存和性能方面的原因 也就是说,生成的序列仍然是“数字的”

由于
NaN
包含以下内容,文件也适用于向上广播:

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

现在这是可能的,因为熊猫版本为0.24.0


Quote:“熊猫已经获得了保存缺少值的整数数据类型的能力。只是想补充一点,如果您试图将浮点(1.143)向量转换为整数(1),将NA转换为新的“Int64”数据类型将给您带来一个错误。为了解决这个问题,您必须对数字进行四舍五入,然后执行”。astype('Int64')”


我的用例是我有一个浮点系列,我想将其舍入为int,但当您这样做时。round()数字末尾的'*.0'仍然保留,因此您可以通过转换为int将该0从末尾删除。

如果文本数据中有空格,通常为整数的列将转换为float64 dtype,因为int64 dtype无法处理空值。如果加载多个包含bl的文件,则可能会导致架构不一致anks(最终将成为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
熊猫新版本1.00+ 您不再(也不能)使用
numpy.nan
。 现在您有了
pandas.NA

请阅读:

IntegerArray目前处于实验阶段。其API或实现可能 毫无预警地改变

在版本1.0.0中更改:现在使用pandas.NA作为缺少的值 而不是numpy.nan

在处理缺失数据的过程中,我们发现熊猫主要使用NaN来 表示缺少的数据。因为NaN是一个浮点,这将强制使用数组 包含任何缺失值的整数的集合,以成为浮点。在某些情况下 在某些情况下,这可能无关紧要。但是如果您的整数列是, 一个标识符,强制转换为浮点可能会有问题 甚至不能表示为浮点数


你能用一个numpy掩码数组吗?我会试试。我还尝试了pandas.DataFrame下的
from_records
函数,使用
强制\u float=False
,但是没有运气…它仍然使新数据具有类型
float64
。是的,没有运气。即使使用掩码数组,它仍然转换为float。看起来pandas是这样的:“哪里有NaN吗?…那么一切都是浮动的。”希望如此
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