我在代码中发现了一个令人讨厌的错误,我忘记将整数从str
转换为int
,然后在排序的整数数组中查找。修复它后,我仍然感到惊讶,这不会导致明确的异常。
这是一个演示:
In [1]: import numpy as np
In [2]: a = np.arange(1000, dtype=int)
In [3]: a.searchsorted('15')
Out[3]: 150
In [4]: a.searchsorted('150')
Out[4]: 150
In [5]: a.searchsorted('1500')
Out[5]: 151
In [6]: a.searchsorted('foo')
Out[6]: 1000
使用float
数组时,这不起作用,引发TypeError: Cannot cast array data from dtype('float64') to dtype('<U32') according to the rule 'safe'
。
我的主要问题是:为什么这不会导致整数数组的异常?
这一点尤为令人惊讶,因为您可以同时执行np.arange(1000, dtype=int).astype(str)
和np.arange(1000, dtype=np.float64).astype(str, casting='safe')
。
附带问题:
'<U32'
?答案 0 :(得分:5)
出现这种情况是因为searchsorted
要求针和干草堆具有相同的dtype。这是使用np.promote_types
实现的,它具有(可能是不幸的)行为:
>>> np.promote_types(int, str)
dtype('S11')
这意味着要获得整数haystack和字符串指针的匹配dtypes,唯一有效的转换是将haystack转换为字符串类型。
一旦我们有了一个共同的dtype,我们会检查它是否可以与np.can_cast
一起使用。这解释了为什么浮点数不会变成字符串,但是整数是:
In [1]: np.can_cast(np.float, np.promote_types(np.float, str))
Out[1]: False
In [2]: np.can_cast(np.int, np.promote_types(np.int, str))
Out[2]: True
总而言之,奇怪的行为是促销规则的组合,其中numeric + string =&gt; string和cast规则,其中int =&gt;字符串是允许的。