使用" safe"将float64转换为int64。

时间:2016-04-08 17:31:40

标签: 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'

我猜我对安全铸造意味着什么有一个根本的误解,所以也许这不是实现这个目标的最好方法,第一个例子有更好的方法可以工作但是第二个例子失败吗? / p>

2 个答案:

答案 0 :(得分:3)

我不知道如何直接在numpy中这样做。我能找到将整数的float dtype数组转换为int dtype数组的最快方法是:

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.

测试正确性:

np.modf

基于https://stackoverflow.com/a/35042794/3776794https://stackoverflow.com/a/7236784/3776794,我尝试使用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

运行时比较:

# Copied from: stackoverflow.com/questions/510357/python-read-a-single-character-from-the-user
def _find_getch():
    try:
        import termios
    except ImportError:
        # Non-POSIX. Return msvcrt's (Windows') getch.
        import msvcrt
        return msvcrt.getch

    # POSIX system. Create and return a getch that manipulates the tty.
    import sys, tty
    def _getch():
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch

    return _getch

getch = _find_getch()

使用Python 3和numpy 1.11.0进行测试。

答案 1 :(得分:2)

你快到了:

if (xdmp:database-name(xdmp:database()) ne 'Schemas') then 
  error(
    QName('', 'NOT-SCHEMAS'), 'make sure the content-source is Schemas')
else
  for $element in doc('tutorial.xsd')/descendant::xs:element
       return if ( $element/@name !="") then
       $element/@name || "|" || $element/@type
       else ()
(: results :)

“安全”与“不安全”的投射仅指dtypes,而不是值。所以,是的,从float64到int64的转换是“不安全的”,因为至少存在一个不能无损地转换为整数的浮点数。