NumPy 中文文档

version: 1.14.0

Built with Teadocs

规则变换

# 规则变换

注意
在NumPy 1.6.0中,创建了一个类型提升API来封装用于确定输出类型的机制。 有关详细信息,请参阅函数result_typepromote_typesmin_scalar_type

每个ufunc的核心是一个一维的跨行循环,它实现特定类型组合的实际函数。当创建一个ufunc时,会给它一个内部循环的静态列表和一个对应的类型签名列表,ufunc对此进行操作。ufunc机器使用此列表来确定对特定情况使用哪个内部循环。你可以检查特定ufunc的“.type”属性,以查看哪些类型组合具有定义的内环,以及它们产生的输出类型(为简洁起见,在所述输出中使用字符代码)。

只要ufunc没有提供输入类型的核心循环实现,就必须对一个或多个输入进行转换。如果找不到输入类型的实现,则该算法搜索具有类型签名的实现,所有输入都可以“安全地”转换到该实现。在所有必要的类型转换之后,选择并执行在循环的内部列表中找到的第一个类型。回想一下,在ufunc期间(甚至对于转换),内部副本被限制为一个内部缓冲区的大小(这是用户可设置的)。

注意
NumPy中的通用函数足够灵活,可以具有混合类型签名。因此,例如,可以定义一个通用函数来处理浮点值和整数值。见ldexp的例子。

通过上面的描述,转换规则本质上是由一个数据类型何时可以“安全地”转换为另一个数据类型的问题来实现的。这个问题的答案可以在Python中通过函数调用来确定:“can_cast(From type,totype)”。下图显示了作者64位系统上24种内部支持类型的调用结果。你可以使用图中给出的代码为你的系统生成此表。

图形:

代码段显示一个32位系统的“可以安全地转换”表。

>>> def print_table(ntypes):
...     print 'X',
...     for char in ntypes: print char,
...     print
...     for row in ntypes:
...         print row,
...         for col in ntypes:
...             print int(np.can_cast(row, col)),
...         print
>>> print_table(np.typecodes['All'])
X ? b h i l q p B H I L Q P e f d g F D G S U V O M m
? 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
b 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
h 0 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0
i 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0
l 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0
q 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0
p 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0
B 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
H 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0
I 0 0 0 0 1 1 1 0 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0
L 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0
Q 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0
P 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0
e 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0
d 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0
g 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 0
F 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0
D 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0
G 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0
S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0
U 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0
V 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
O 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
M 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

你应该注意到,虽然表中包含了“S”、“U”和“V”类型,但不能由ufunc对它们进行操作。另外,请注意,在32位系统中,整数类型可能有不同的大小,导致表略有改变。

混合标量数组操作使用一组不同的转换规则,以确保标量不能“向上转换”数组,除非标量与数组具有根本不同的数据类型(即数据类型层次结构中的不同层次结构)。这条规则使你可以在代码中使用标量常量(作为Python类型,在函数中相应地进行解释),而不必担心标量常量的精度是否会导致大(小精度)数组的上行。