为什么当你把一个numpy数组乘以一个等于或大于10**20的数时,这个数组的dtype会自动变成'object'?

wgx48brx  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(108)

给定一个任意的numpy数组(其大小和形状似乎不起作用)

import numpy as np

a = np.array([1.])
print(a.dtype)  # float64

如果将其乘以等于或大于10**20的数字,则会更改其dtype

print((a*10**19).dtype)  # float64
print((a*10**20).dtype)  # object

a *= 10**20  # Throws TypeError: ufunc 'multiply' output (typecode 'O') 
#             could not be coerced to provided output parameter (typecode 'd') 
#             according to the casting rule ''same_kind''

a *= 10.**20  # Throws numpy.core._exceptions._UFuncOutputCastingError: 
#             Cannot cast ufunc 'multiply' output from dtype('float64') to 
#             dtype('int32') with casting rule 'same_kind'

但是,如果您将元素相乘,则不会发生这种情况

a[0] *= 10**20  
print(a, a.dtype)  # [1.e+20] float64

或将数字转换为float(或int

a *= float(10**20)  
print(a, a.dtype)  # [1.e+20] float64

仅供参考,如果在numpy之外执行乘法,则不会出现问题

b = 1.
print(type(b), type(10**20), type(10.**20))  # float int float

b *= 10**20
print(type(b))  # float
cigdeys3

cigdeys31#

我希望它是一个“自然”整数在系统上所能呈现的大小。

print(sys.maxsize, sys.getsizeof(sys.maxsize))
=> 9223372036854775807 36
print(10**19, sys.getsizeof(10**19))
=> 10000000000000000000 36

这就是 * 在我的系统上 * 开始向object转换的地方,当我这样做时

for i in range(1, 24):
    print(f'type of a*10**{i}:', (a * 10**i).dtype)

我确实期望它与整数的实现相联系:
PEP 0237:本质上,long重命名为int。也就是说,只有一个内置的整型,名为int;但它的行为与旧的long类型基本相同。
请访问https://docs.python.org/3.1/whatsnew/3.0.html#integers
要注意这一点,可以使用numpy.multiply和强制输出类型,这将抛出一个错误,并且不会进行静默转换(类似于*=示例)。

相关问题