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