我有一个numpy数组:
>>> b
array([[ 2, 2],
[ 6, 4],
[10, 6]])
我想将第一列乘以浮点数,结果我需要int数,因为当我这样做时:
>>> b[:,0] *= 2.1
它说:
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
我需要看起来像这样的数组:
array([[ 4, 2],
[12, 4],
[21, 6]])
andrew_reece..
6
@Umang Gupta解决了你的问题.我很好奇为什么这个有用,所以我发布了我发现的附加上下文.FWIW这个问题已经在这里被问到并回答了,但是这个答案也没有像我希望的那样真正地了解正在发生的事情,所以这是我的尝试:
使用*=
运算符调用__imul__()
Numpy ndarrays的就地乘法的特殊方法,后者又调用通用函数(ufunc)multiply()
.
这里有两个multiply()
相关的参数:out
和casting
.
所述out
参数指定的输出(与它的类型一起).在就地乘法运算符中,out
设置为self
,即ndarray
调用乘法运算的对象.特别是,确切的调用了*=
这个样子的:
ufunc(self, other, out=(self,))
^ where ufunc = multiply
,self = b
(ndarray
,type int64
,and other = 2.1
(scalar,type float
)
casting
但是,该参数确定了由于操作而允许哪种数据类型转换的规则. 从Numpy 1.10开始,默认值为casting
is same_kind
,表示:
只允许使用float64到float32之类的安全转换或类型转换
由于我们的ufunc
电话没有指定的值casting
参数,默认值(same_kind
)用于-但因为我们这会导致问题已经指定out
为具有int64
D型细胞,这是不是同一种与int-通过流通倍增的输出.使用same_kind
强制转换时,float
操作的结果无法转换为int
.这就是我们看到这个错误的原因.
我们可以使用multiply()
显式复制此错误:
np.multiply(b, 2.1, out=b)
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
通过设置参数值可以放宽casting
要求.然后,当设置时,输出被强制转换为类型,无论它是否相同(如果可能):multiply()
"unsafe"
out
out
np.multiply(b, 2.1, out=b, casting="unsafe")
# specifying int output and allowing casting to be "unsafe" allows re-conversion to int
array([[ 4, 4],
[12, 8],
[21, 12]])
b[:,0]
另一方面,使用常规赋值运算符进行更新是可以的.这就是@Umang Gupta的解决方案.
附:
b[:,0] = b[:,0]* 2.1
*
调用multiply
ufunc,就像调用一样*=
.但由于它没有调用操作的原位版本,因此没有out
指定参数,因此输出没有设置类型.然后,标准类型转换允许整数向上浮动:
np.multiply(b, 2.1)
# float output
array([[ 4.2, 4.2],
[ 12.6, 8.4],
[ 21. , 12.6]])
然后,正常赋值运算符=
获取乘法的输出并将其存储b[:,0]
.根据Numpy文档为索引数组赋值:
请注意,如果将较高类型分配给较低类型(如浮点数到整数),则分配可能会导致更改
所以,问题的关键在于*=
运营商的自动的设定out
参数不改变casting
从论证same_kind
到unsafe
.(并不是说这是一个错误,只是因为这就是你得到错误的原因.)并且通过利用Numpy中赋值的自动"向下转换"属性,接受的解决方案可以解决这个问题.希望有所帮助!(另外,Numpy专业人士,请随时纠正我的任何误解.)
1> andrew_reece..:
@Umang Gupta解决了你的问题.我很好奇为什么这个有用,所以我发布了我发现的附加上下文.FWIW这个问题已经在这里被问到并回答了,但是这个答案也没有像我希望的那样真正地了解正在发生的事情,所以这是我的尝试:
使用*=
运算符调用__imul__()
Numpy ndarrays的就地乘法的特殊方法,后者又调用通用函数(ufunc)multiply()
.
这里有两个multiply()
相关的参数:out
和casting
.
所述out
参数指定的输出(与它的类型一起).在就地乘法运算符中,out
设置为self
,即ndarray
调用乘法运算的对象.特别是,确切的调用了*=
这个样子的:
ufunc(self, other, out=(self,))
^ where ufunc = multiply
,self = b
(ndarray
,type int64
,and other = 2.1
(scalar,type float
)
casting
但是,该参数确定了由于操作而允许哪种数据类型转换的规则. 从Numpy 1.10开始,默认值为casting
is same_kind
,表示:
只允许使用float64到float32之类的安全转换或类型转换
由于我们的ufunc
电话没有指定的值casting
参数,默认值(same_kind
)用于-但因为我们这会导致问题已经指定out
为具有int64
D型细胞,这是不是同一种与int-通过流通倍增的输出.使用same_kind
强制转换时,float
操作的结果无法转换为int
.这就是我们看到这个错误的原因.
我们可以使用multiply()
显式复制此错误:
np.multiply(b, 2.1, out=b)
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
通过设置参数值可以放宽casting
要求.然后,当设置时,输出被强制转换为类型,无论它是否相同(如果可能):multiply()
"unsafe"
out
out
np.multiply(b, 2.1, out=b, casting="unsafe")
# specifying int output and allowing casting to be "unsafe" allows re-conversion to int
array([[ 4, 4],
[12, 8],
[21, 12]])
b[:,0]
另一方面,使用常规赋值运算符进行更新是可以的.这就是@Umang Gupta的解决方案.
附:
b[:,0] = b[:,0]* 2.1
*
调用multiply
ufunc,就像调用一样*=
.但由于它没有调用操作的原位版本,因此没有out
指定参数,因此输出没有设置类型.然后,标准类型转换允许整数向上浮动:
np.multiply(b, 2.1)
# float output
array([[ 4.2, 4.2],
[ 12.6, 8.4],
[ 21. , 12.6]])
然后,正常赋值运算符=
获取乘法的输出并将其存储b[:,0]
.根据Numpy文档为索引数组赋值:
请注意,如果将较高类型分配给较低类型(如浮点数到整数),则分配可能会导致更改
所以,问题的关键在于*=
运营商的自动的设定out
参数不改变casting
从论证same_kind
到unsafe
.(并不是说这是一个错误,只是因为这就是你得到错误的原因.)并且通过利用Numpy中赋值的自动"向下转换"属性,接受的解决方案可以解决这个问题.希望有所帮助!(另外,Numpy专业人士,请随时纠正我的任何误解.)