Numpy就地数据类型转换
16Gb机器出现内存不足错误。我怀疑转换是否真的到位Numpy就地数据类型转换,numpy,memory,type-conversion,Numpy,Memory,Type Conversion,16Gb机器出现内存不足错误。我怀疑转换是否真的到位 import numpy as np x = np.ones(int(1.5e9), dtype=np.int64) # 12 Gb x.astype(np.float64, copy=False) # gives out of memory error. 如何进行就地内存转换?我想转换数据类型并保留值。例如,1.0f变为整数1 关于copy参数: 默认情况下,astype始终返回新分配的数组。如果这 设置为false,并且dtype、
import numpy as np
x = np.ones(int(1.5e9), dtype=np.int64) # 12 Gb
x.astype(np.float64, copy=False) # gives out of memory error.
如何进行就地内存转换?我想转换数据类型并保留值。例如,1.0f变为整数1
关于
copy
参数:
默认情况下,astype始终返回新分配的数组。如果这
设置为false,并且dtype
、order
和subok
如果满足要求,则返回输入数组
一份副本的副本
所以这是有条件的
In [540]: x=np.arange(10)
In [542]: x.dtype
Out[542]: dtype('int32')
In [543]: z=x.astype('float32',copy=False)
In [544]: z
Out[544]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32)
In [545]: x.__array_interface__
Out[545]:
{'data': (188221848, False),
'descr': [('', '<i4')],
'shape': (10,),
'strides': None,
'typestr': '<i4',
'version': 3}
In [546]: z.__array_interface__
Out[546]:
{'data': (191273640, False),
'descr': [('', '<f4')],
'shape': (10,),
'strides': None,
'typestr': '<f4',
'version': 3}
这是因为z
与x
共享内存,但使用不同的dtype
。从x
复制到z
时,它们将被转换为与新的数据类型匹配。内存位置被保留。然而,我不能保证没有临时缓冲区
如果不清楚,从
int32
转换为float32
需要更改基础字节。整数的位表示不同于浮点数的位表示
In [594]: np.array(1, 'int32').tobytes()
Out[594]: b'\x01\x00\x00\x00'
In [595]: np.array(1, 'float32').tobytes()
Out[595]: b'\x00\x00\x80?'
关于
copy
参数:
默认情况下,astype始终返回新分配的数组。如果这
设置为false,并且dtype
、order
和subok
如果满足要求,则返回输入数组
一份副本的副本
所以这是有条件的
In [540]: x=np.arange(10)
In [542]: x.dtype
Out[542]: dtype('int32')
In [543]: z=x.astype('float32',copy=False)
In [544]: z
Out[544]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32)
In [545]: x.__array_interface__
Out[545]:
{'data': (188221848, False),
'descr': [('', '<i4')],
'shape': (10,),
'strides': None,
'typestr': '<i4',
'version': 3}
In [546]: z.__array_interface__
Out[546]:
{'data': (191273640, False),
'descr': [('', '<f4')],
'shape': (10,),
'strides': None,
'typestr': '<f4',
'version': 3}
这是因为z
与x
共享内存,但使用不同的dtype
。从x
复制到z
时,它们将被转换为与新的数据类型匹配。内存位置被保留。然而,我不能保证没有临时缓冲区
如果不清楚,从
int32
转换为float32
需要更改基础字节。整数的位表示不同于浮点数的位表示
In [594]: np.array(1, 'int32').tobytes()
Out[594]: b'\x01\x00\x00\x00'
In [595]: np.array(1, 'float32').tobytes()
Out[595]: b'\x00\x00\x80?'
可能可以分部分做<代码>y=x.view(dtype=np.float64);y[:10000]=x[:10000].aType(np.float64)您链接到的问题如何不足以解决您的问题?对我来说像是一个完全复制品。可能可以分部分来做<代码>y=x.view(dtype=np.float64);y[:10000]=x[:10000].aType(np.float64)您链接到的问题如何不足以解决您的问题?在我看来,这是一个完全相同的副本。float32和int32都使用相同的内存量。但是astype仍然会生成新的副本,这是不必要的,而且效率低下……效率和它有什么关系呢。每个4字节块必须经过相同的转换过程。无论它被写回同一个或不同的内存位置,在“速度”上都不会有太大的差别。我想复制要比就地操作慢,因为cpu不必读/写额外的内存缓存线。预取应屏蔽内存延迟。不知道如果没有拷贝,预取是否会更好。复制肯定会降低内存效率。对于非常大的阵列,内存缓存可能会有问题。我只是做了一些计时。对于
arange(10000)
第二种方法稍微快一些;对于arange(1000000)
15x。时间仍在ns/µs范围内。z[:]=x
将重写所有数据“是”(原地)z
float是查看它们的正确方式x.view('float32')
显示正确的1.0
。float32和int32使用相同的内存量。但是astype仍然会生成新的副本,这是不必要的,而且效率低下……效率和它有什么关系呢。每个4字节块必须经过相同的转换过程。无论它被写回同一个或不同的内存位置,在“速度”上都不会有太大的差别。我想复制要比就地操作慢,因为cpu不必读/写额外的内存缓存线。预取应屏蔽内存延迟。不知道如果没有拷贝,预取是否会更好。复制肯定会降低内存效率。对于非常大的阵列,内存缓存可能会有问题。我只是做了一些计时。对于arange(10000)
第二种方法稍微快一些;对于arange(1000000)
15x。时间仍在ns/µs范围内。z[:]=x
将重写所有数据“是”(原地)z
float是查看它们的正确方式x.view('float32')
显示正确的1.0
。