簡體   English   中英

使用“安全”將float64轉換為int64

[英]Convert float64 to int64 using “safe”

我想將NumPy(版本1.11.0)數組從float64int64 我希望此操作能夠在整數上完成,但在非整數上失敗。

我的理解是我可以使用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進行了測試。

你快到了:

In [7]: a = np.array([1.1, 2.2, 3.3])

In [8]: a.astype(int) == a
Out[8]: array([False, False, False], dtype=bool)

In [9]: if (a.astype(int) != a).any():
   ...:     raise ValueError("Conversion failed")
   ...: 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-9-3628e8ae2ce8> in <module>()
      1 if (a.astype(int) != a).any():
----> 2     raise ValueError("Conversion failed")
      3 

ValueError: Conversion failed

In [10]: b = np.array([1.0, 2.0, 3.0])

In [11]: b.astype(int) == b
Out[11]: array([ True,  True,  True], dtype=bool)

“安全”與“不安全”強制轉換僅是指dtype,而不是值。 因此,是的,從float64到int64的轉換是“不安全的”,因為存在至少一個不能無損地轉換為整數的浮點數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM