是否有一种首选的方法来保持numpy数组的数据类型固定为int(或int64或其他),同时仍然有一个元素列在numpy. nan中?

特别是,我正在将一个内部数据结构转换为Pandas DataFrame。在我们的结构中,我们有整数类型的列,这些列仍然有NaN(但是列的dtype是int)。如果我们把它设为DataFrame,它似乎把所有东西都重铸为浮点数,但我们希望它是int。

想法吗?

试过的东西:

我尝试在pandas下使用from_records()函数。DataFrame,与coerce_float=False,这没有帮助。我还尝试使用NumPy掩码数组,使用NaN fill_value,这也没有工作。所有这些都会导致列数据类型变成浮点数。


当前回答

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

熊猫0.24。X发行说明 引用:“Pandas已经获得了保存缺少值的整型dtypes的能力。

其他回答

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

熊猫0.24。X发行说明 引用:“Pandas已经获得了保存缺少值的整型dtypes的能力。

如果文本数据中有空格,则通常为整数的列将被转换为float64 dtype类型的浮点数,因为int64 dtype不能处理空值。这可能导致模式不一致,如果您加载多个文件,其中一些带有空格(最终将为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

熊猫 v0.24+

支持整数序列NaN的功能将在v0.24以上可用。在v0.24的“新内容”部分中有关于这方面的信息,更多详细信息在可空整数数据类型中。

Pandas v0.23及更早的版本

一般来说,最好在可能的情况下使用float系列,即使当该系列由于包含NaN值而从int向上转换为float时也是如此。这支持基于numpy的向量化计算,否则将处理python级循环。

文档建议:“一种可能是使用dtype=对象数组。”例如:

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被认为是浮点数。目前的文档(从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

如果您试图将浮点(1.143)向量转换为整数(1),并且该向量具有NAs,则将其转换为新的'Int64' dtype将会给您一个错误。为了解决这个问题,你必须四舍五入的数字,然后做".astype('Int64')"

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

我的用例是,我有一个浮点系列,我想四舍五入到int,但当你做。round()仍然有小数,你需要转换为int删除小数。

从版本0.24开始,这个功能已经被添加到pandas中。

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