programing

NumPy 배열의 임플레이스 유형 변환

jooyons 2023. 8. 13. 09:40
반응형

NumPy 배열의 임플레이스 유형 변환

다음의 NumPy 배열이 지정됩니다.int32로 변환하려면 어떻게 해야 합니까?float32 제자리에?그래서 기본적으로, 저는 하고 싶습니다.

a = a.astype(numpy.float32)

배열을 복사하지 않고 사용할 수 있습니다.그것은 큽니다.

이 작업을 수행하는 이유는 다음의 계산을 위한 두 가지 알고리즘이 있기 때문입니다.a그 중 하나는 다음의 배열을 반환합니다.int32다른 하나는 의 배열을 반환합니다.float32(그리고 이것은 두 개의 다른 알고리즘에 내재되어 있습니다.)모든 추가 계산은 다음과 같이 가정합니다.a의 배열입니다.float32.

현재 저는 다음을 통해 C 함수로 변환합니다.ctypes파이썬에서 이것을 할 수 있는 방법이 있습니까?

업데이트: 이 기능은 가능한 경우에만 복사를 방지하므로 이 질문에 대한 정답이 아닙니다.우넛부의 답은 옳은 답입니다.


a = a.astype(numpy.float32, copy=False)

numpy 형식에 복사 플래그가 있습니다.왜 우리는 그것을 사용하면 안 되나요?

다른 dtype으로 보기를 만든 다음 보기에 내부 복사할 수 있습니다.

import numpy as np
x = np.arange(10, dtype='int32')
y = x.view('float32')
y[:] = x

print(y)

수확량

array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.], dtype=float32)

변환이 제자리에 있었다는 것을 보여주기 위해 복사 위치 x로.y변경된x:

print(x)

인쇄물

array([         0, 1065353216, 1073741824, 1077936128, 1082130432,
       1084227584, 1086324736, 1088421888, 1090519040, 1091567616])

다음과 같이 변환하지 않고 어레이 유형을 변경할 수 있습니다.

a.dtype = numpy.float32

그러나 먼저 모든 정수를 해당 부동 소수로 해석되는 것으로 변경해야 합니다.이를 위한 매우 느린 방법은 파이썬의struct다음과 같은 모듈:

def toi(i):
    return struct.unpack('i',struct.pack('f',float(i)))[0]

...어레이의 각 구성원에게 적용됩니다.

하지만 아마 더 빠른 방법은 numpy의 ctypeslib 도구를 사용하는 것일 것입니다(제가 잘 모릅니다).

편집 -

ctypeslib가 작동하지 않는 것 같으니 일반적인 것으로 변환을 진행하겠습니다.numpy.astype메모리 제한 내의 블록 크기로 진행합니다.

a[0:10000] = a[0:10000].astype('float32').view('int32')

완료되면 dtype을 변경합니다.

다음은 호환되는 dtype에 대한 작업을 수행하고 블록 크기에 대한 사용자 제어를 통해 임의의 모양 배열을 처리하는 함수입니다.

import numpy

def astype_inplace(a, dtype, blocksize=10000):
    oldtype = a.dtype
    newtype = numpy.dtype(dtype)
    assert oldtype.itemsize is newtype.itemsize
    for idx in xrange(0, a.size, blocksize):
        a.flat[idx:idx + blocksize] = \
            a.flat[idx:idx + blocksize].astype(newtype).view(oldtype)
    a.dtype = newtype

a = numpy.random.randint(100,size=100).reshape((10,10))
print a
astype_inplace(a, 'float32')
print a

데이터를 읽는 데 소요된 시간

t1=time.time() ; V=np.load ('udata.npy');t2=time.time()-t1 ; print( t2 )

95.7923333644867

V.dtype

dtype('>f8')

V.shape

(3072, 1024, 4096)

**새 배열 만들기 **

t1=time.time() ; V64=np.array( V, dtype=np.double); t2=time.time()-t1 ; print( t2 )

1291.669689655304

단순 인플레이스 numpy 변환

t1=time.time() ; V64=np.array( V, dtype=np.double); t2=time.time()-t1 ; print( t2 )

205.64322113990784

유형 사용

t1=time.time() ; V = V.astype(np.double) ; t2=time.time()-t1 ; print( t2 )

400.6731758117676

보기 사용

t1=time.time() ; x=V.view(np.double);V[:,:,:]=x ;t2=time.time()-t1 ; print( t2 )

556.5982494354248

변수를 지울 때마다 확인합니다.따라서 단순히 파이썬이 변환을 처리하도록 하는 것이 가장 효율적입니다.

import numpy as np
arr_float = np.arange(10, dtype=np.float32)
arr_int = arr_float.view(np.float32)

view()와 매개 변수 'dtype'을 사용하여 배열을 변경합니다.

사용:

In [105]: a
Out[105]: 
array([[15, 30, 88, 31, 33],
       [53, 38, 54, 47, 56],
       [67,  2, 74, 10, 16],
       [86, 33, 15, 51, 32],
       [32, 47, 76, 15, 81]], dtype=int32)

In [106]: float32(a)
Out[106]: 
array([[ 15.,  30.,  88.,  31.,  33.],
       [ 53.,  38.,  54.,  47.,  56.],
       [ 67.,   2.,  74.,  10.,  16.],
       [ 86.,  33.,  15.,  51.,  32.],
       [ 32.,  47.,  76.,  15.,  81.]], dtype=float32)

a = np.subtract(a, 0., dtype=np.float32)

언급URL : https://stackoverflow.com/questions/4389517/in-place-type-conversion-of-a-numpy-array

반응형