安全地将浮点型转换为最小的整数类型

时间:2019-04-18 20:27:27

标签: python pandas numpy

Pandas和numpy有多种更改数值类型的方法,但是我无法找到一种自动的方法来安全地将浮点数转换为可能的最小整数,因为不会丢失任何数值信息。

例如:

1.0 (float32)  ->  1 (int32)   # OK, 1 == 1.0
1.0 (float32)  ->  1 (int8)    # also OK, just more compact storage
1.4 (float32)  ->  1 (int8)    # not OK, 1 != 1.1

以下是一些示例数据:

df=pd.DataFrame({ 'i':[1.,333,555_666_777_888],
                  'j':[1.,333,555_666],
                  'x':np.random.randn(3) })

看起来像这样(dtypes都是float64):

              i         j         x
0  1.000000e+00       1.0  0.852965
1  3.330000e+02     333.0 -0.955869
2  5.556668e+11  555666.0 -0.023493

所需的转换

              i       j         x
0             1       1 -2.304234
1           333     333 -0.652469
2  555666777888  555666 -1.218302

具有dtypes:

i      int64
j      int32
x    float64

我将提供一个简单的方法作为答案,但是也许有更好的方法,或者也许这已经是熊猫或numpy的一部分,但我没有意识到。

我也正试着回答答案(NaNs)中的缺失值,因为我没有最新版本的pandas(24.x),它不允许整数为NaN,所以也许有人想在其中解决一个答案。

请注意,在此问题中提到的将浮点数转换为整数的方法很少:Convert floats to ints in Pandas?,但是没有一种方法可以解决在将2.1转换为2时潜在的数值精度损失。

1 个答案:

答案 0 :(得分:0)

这是一个简单的功能:

def float_to_int( s ):
    if ( s.astype(np.int64) == s ).all():
        return pd.to_numeric( s, downcast='integer' )
    else:
        return s

df.apply( float_to_int )

输出:

              i       j         x
0             1       1 -2.304234
1           333     333 -0.652469
2  555666777888  555666 -1.218302

使用dtypes:

i      int64
j      int32
x    float64

说明:

我找不到将浮点数转换为整数的自动安全方法,所以我只是检查将列转换为整数是否会更改值。如果没有,那么我允许将类型从float转换为int。请注意,int默认为np.int32,因此使用np.int64可以更好地将其从float转换为int。

此后,pandas使用to_numeric()完成所有工作,因为它将自动转换为最小的整数类型。