为什么numpy在调用searchsorted时会默默地将我的int数组转换为字符串?

时间:2015-07-09 18:02:50

标签: python arrays numpy type-conversion binary-search

我在代码中发现了一个令人讨厌的错误,我忘记将整数从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'

1 个答案:

答案 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;字符串是允许的。