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

Why does numpy silently convert my int array to strings when calling searchsorted?

我在我的代码中发现了一个讨厌的错误,我忘记在排序的整数数组中查找之前将整数从 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')

附带问题:

发生此行为是因为 searchsorted 要求针和干草堆具有相同的数据类型。这是使用 np.promote_types 实现的,它具有(可能不幸的)行为:

>>> np.promote_types(int, str)
dtype('S11')

这意味着要为整数 haystack 和字符串 needle 获取匹配的数据类型,唯一有效的转换是将 haystack 转换为字符串类型。

一旦我们有了通用的数据类型,我们就会检查它是否可以与 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

总而言之,奇怪的行为是数字 + 字符串 => 字符串的提升规则和允许 int => 字符串的转换规则的组合。