为什么 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')
。
附带问题:
- 为什么要转换整个数组而不是参数?
- 为什么搜索字符串转换为
'<U32'
?
发生此行为是因为 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 => 字符串的转换规则的组合。
我在我的代码中发现了一个讨厌的错误,我忘记在排序的整数数组中查找之前将整数从 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'
?
发生此行为是因为 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 => 字符串的转换规则的组合。