python - 使用 "safe"将 float64 转换为 int64

标签 python numpy casting floating-point int

我想将 NumPy(版本 1.11.0)数组从 float64 转换为 int64。我希望此操作能够对整数完成但对非整数失败。

我的理解是我可以使用 casting=safe 虽然显然我的理解是错误的...

我希望以下内容会起作用:

np.array([1.0]).astype(int, casting='safe')

而且这会失败:

np.array([1.1]).astype(int, casting='safe')

但是他们都因这个错误而失败:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-51-7261ddf00794> in <module>()
    1 import numpy as np
    2 print(np.__version__)
----> 3 np.array([1.0]).astype(int, casting='safe')

TypeError: Cannot cast array from dtype('float64') to dtype('int64') according to the rule 'safe'

我猜我对安全转换的含义存在根本性的误解,所以这可能不是实现此目的的最佳方法,是否有更好的方法让第一个示例工作但第二个示例失败?

最佳答案

我不知道有什么方法可以直接在 numpy 中执行此操作。我能找到的将整数的 float dtype 数组转换为 int dtype 数组的最快方法是:

import numpy as np

def float_to_int(array):
    int_array = array.astype(int, casting='unsafe', copy=True)
    if not np.equal(array, int_array).all():
        raise TypeError("Cannot safely convert float array to int dtype. "
                        "Array must only contain whole numbers.")
    return int_array

正确性测试:

In [3]: whole_numbers = np.arange(1000000, dtype=float)

In [4]: fractional = np.arange(0, 100000, 0.1, dtype=float)

In [5]: float_to_int(whole_numbers)
Out[5]: array([     0,      1,      2, ..., 999997, 999998, 999999])

In [6]: float_to_int(fractional)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-0a7807a592b7> in <module>()
----> 1 float_to_int(fractional)

<ipython-input-2-953668ae0922> in float_to_int(array)
      2         int_array = array.astype(int, casting='unsafe', copy=True)
      3         if not np.equal(array, int_array).all():
----> 4                 raise TypeError("Cannot safely convert float array to int dtype. "
      5                                 "Array must only contain whole numbers.")
      6         return int_array

TypeError: Cannot safely convert float array to int dtype. Array must only contain whole numbers.

基于 https://stackoverflow.com/a/35042794/3776794https://stackoverflow.com/a/7236784/3776794我尝试了一个使用 np.modf 的实现,但这比上面的解决方案慢:

def float_to_int_mod(array):
    mod_array, int_array = np.modf(array)
    if not np.equal(mod_array, 0).all():
        raise TypeError("Cannot safely convert float array to int dtype. "
                        "Array must only contain whole numbers.")
    return int_array.astype(int, casting='unsafe', copy=True)

运行时比较:

In [8]: %timeit float_to_int(whole_numbers)
100 loops, best of 3: 2.75 ms per loop

In [9]: %timeit float_to_int_mod(whole_numbers)
100 loops, best of 3: 8.74 ms per loop

这是用 Python 3 和 numpy 1.11.0 测试的。

关于python - 使用 "safe"将 float64 转换为 int64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36505879/

相关文章:

python - Pandas 在 python Pandas 数据框中获取两行之间交集的方法

c# - 将 PropertyInfo 转换为通用类型

java - 将 2D 对象数组的列转换为 1D 字符串数组

python - 安装 OpenCV for Python(多个 python 版本)

python - 启动停止守护进程和 python

PYTHON - 计算 NdArray 中的最小值和最小值索引

python - 如何检查对象在列表理解中是否不是 None?

python - 如何将 PIL(或任何模块)安装到树莓派上?

python - Python 3 中数据的图形选择

python - 解包列表并同时转换