Numpy就地数据类型转换

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、

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
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