import numpy as np
u = np.array([1, 2, -1], dtype=object)
v = np.array([-1, 1, 0], dtype=object)
np.cross(u, v)
失败并显示
numpy._core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'multiply' output from dtype('O') to dtype('int64') with casting rule 'same_kind'
。
np.dot(u, v)
按预期工作。
使用
dtype=object
,因为使用实际数据进行计算会溢出int64
并给出错误的结果(没有警告)。实际值是大约 15 位有效数字(50 位二进制数字)的整数。
一种解决方法是将所有值设为小数:
u = np.array(list(map(Decimal, [1, 2, -1])))
v = np.array(list(map(Decimal, [-1, 1, 0])))
np.cross(u, v)
使用 numpy 有更好的解决方法吗?
np.cross
中有一个块可以让临时结果数组变成int32
。
我更正的那个块是:
...: assert a.shape[-1] == 3
...: if b.shape[-1] == 3:
...: # cp0 = a1 * b2 - a2 * b1
...: # cp1 = a2 * b0 - a0 * b2
...: # cp2 = a0 * b1 - a1 * b0
...: np.multiply(a1, b2, out=cp0)
...: tmp = np.array(a2 * b1, dtype=cp.dtype) # correct dtype
...: print(tmp,tmp.dtype, cp0.dtype)
...: cp0 -= tmp
...: np.multiply(a2, b0, out=cp1)
...: np.multiply(a0, b2, out=tmp)
...: cp1 -= tmp
...: np.multiply(a0, b1, out=cp2)
...: np.multiply(a1, b0, out=tmp)
...: cp2 -= tmp
使用您的对象数据类型数组:
In [384]: u = np.array([1, 2, -1], dtype=object)
...: v = np.array([-1, 1, 0], dtype=object)
np.cross
引发涉及此的错误 tmp
:
In [385]: np.cross(u,v)
---------------------------------------------------------------------------
UFuncTypeError Traceback (most recent call last)
Cell In[385], line 1
----> 1 np.cross(u,v)
File <__array_function__ internals>:200, in cross(*args, **kwargs)
File ~\miniconda3\lib\site-packages\numpy\core\numeric.py:1669, in cross(a, b, axisa, axisb, axisc, axis)
1667 cp0 -= tmp
1668 multiply(a2, b0, out=cp1)
-> 1669 multiply(a0, b2, out=tmp)
1670 cp1 -= tmp
1671 multiply(a0, b1, out=cp2)
UFuncTypeError: Cannot cast ufunc 'multiply' output from dtype('O') to dtype('int32') with casting rule 'same_kind'
考虑到输入的数据类型,cp
之前已创建为返回数组。
In [387]: mycross(u,v)
object
-1 object object
Out[387]: array([1, 1, 3], dtype=object)
a1
和 b2
是 a
和 b
的元素(实际上是列),例如a1=a[...,0]
。 因此,它们不会保留整个数组 dtype - 除非您使用 Decimal
或 mpmath.mpi
。