Programing

Numpy : 2 개의 실제 배열로 복잡한 배열을 만드시나요?

lottogame 2021. 1. 10. 16:45
반응형

Numpy : 2 개의 실제 배열로 복잡한 배열을 만드시나요?


이게 그렇게 쉬워야한다고 맹세 컨데 ... 왜 안돼? :(

사실, 동일한 배열의 두 부분을 결합하여 복잡한 배열을 만들고 싶습니다.

Data[:,:,:,0] , Data[:,:,:,1]

작동하지 않습니다.

x = np.complex(Data[:,:,:,0], Data[:,:,:,1])
x = complex(Data[:,:,:,0], Data[:,:,:,1])

내가 뭔가를 놓치고 있습니까? numpy는 복소수에 대해 배열 함수를 수행하는 것을 좋아하지 않습니까? 오류는 다음과 같습니다.

TypeError: only length-1 arrays can be converted to Python scalars

이것은 당신이 원하는 것을하는 것 같습니다.

numpy.apply_along_axis(lambda args: [complex(*args)], 3, Data)

다음은 또 다른 해결책입니다.

# The ellipsis is equivalent here to ":,:,:"...
numpy.vectorize(complex)(Data[...,0], Data[...,1])

그리고 또 다른 간단한 솔루션 :

Data[...,0] + 1j * Data[...,1]

추신 : 메모리를 절약하려는 경우 (중간 어레이 없음) :

result = 1j*Data[...,1]; result += Data[...,0]

아래 devS의 솔루션도 빠릅니다.


물론 다소 명백한 것이 있습니다.

Data[...,0] + 1j * Data[...,1]

실수와 허수 부분이 마지막 차원을 따라 슬라이스이고 배열이 마지막 차원을 따라 연속적이라면 그냥 할 수 있습니다

A.view(dtype=np.complex128)

단 정밀도 부동을 사용하는 경우 이것은 다음과 같습니다.

A.view(dtype=np.complex64)

다음은 더 자세한 예입니다.

import numpy as np
from numpy.random import rand
# Randomly choose real and imaginary parts.
# Treat last axis as the real and imaginary parts.
A = rand(100, 2)
# Cast the array as a complex array
# Note that this will now be a 100x1 array
A_comp = A.view(dtype=np.complex128)
# To get the original array A back from the complex version
A = A.view(dtype=np.float64)

캐스팅에서 남는 여분의 차원을 제거하려면 다음과 같이 할 수 있습니다.

A_comp = A.view(dtype=np.complex128)[...,0]

이것은 메모리에서 복소수가 실제로 두 개의 부동 소수점 숫자이기 때문에 작동합니다. 첫 번째는 실수 부분을 나타내고 두 번째는 허수 부분을 나타냅니다. 배열의보기 방법은 인접한 두 부동 소수점 값을 단일 복소수로 처리하고 그에 따라 차원을 업데이트하려는 것을 반영하도록 배열의 dtype을 변경합니다.

이 메서드는 배열의 값을 복사하거나 새로운 계산을 수행하지 않으며 동일한 메모리 블록을 다르게 보는 새로운 배열 객체를 만드는 것뿐입니다. 따라서 값 복사와 관련된 작업보다 훨씬 빠르게이 작업을 수행 할 수 있습니다 . 또한 복소수 배열에서 변경 한 사항이 실수 부와 허수 부로 배열에 반영된다는 의미이기도합니다.

유형 캐스트 ​​직후에 추가 축을 제거하면 원래 배열을 복구하는 것이 약간 까다로울 수 있습니다. 상황이 좋아 A_comp[...,np.newaxis].view(np.float64)이 글을 작성로서, NumPy와 새로운 축이 추가 될 때 배열이 여전히 C-연속 것을 감지하지 않습니다 때문에 없습니다 현재 작업을한다. 이 문제를 참조하십시오 . A_comp.view(np.float64).reshape(A.shape)그래도 대부분의 경우 작동하는 것 같습니다.


This is what your are looking for:

from numpy import array

a=array([1,2,3])
b=array([4,5,6])

a + 1j*b

->array([ 1.+4.j,  2.+5.j,  3.+6.j])

I am python novice so this may not be the most efficient method but, if I understand the intent of the question correctly, steps listed below worked for me.

>>> import numpy as np
>>> Data = np.random.random((100, 100, 1000, 2))
>>> result = np.empty(Data.shape[:-1], dtype=complex)
>>> result.real = Data[...,0]; result.imag = Data[...,1]
>>> print Data[0,0,0,0], Data[0,0,0,1], result[0,0,0]
0.0782889873474 0.156087854837 (0.0782889873474+0.156087854837j)

import numpy as np

n = 51 #number of data points
# Suppose the real and imaginary parts are created independently
real_part = np.random.normal(size=n)
imag_part = np.random.normal(size=n)

# Create a complex array - the imaginary part will be equal to zero
z = np.array(real_part, dtype=complex)
# Now define the imaginary part:
z.imag = imag_part
print(z)

If you really want to eke out performance (with big arrays), numexpr can be used, which takes advantage of multiple cores.

Setup:

>>> import numpy as np
>>> Data = np.random.randn(64, 64, 64, 2)
>>> x, y = Data[...,0], Data[...,1]

With numexpr:

>>> import numexpr as ne
>>> %timeit result = ne.evaluate("complex(x, y)")
573 µs ± 21.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Compared to fast numpy method:

>>> %timeit result = np.empty(x.shape, dtype=complex); result.real = x; result.imag = y
1.39 ms ± 5.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

That worked for me:

input:

[complex(a,b) for a,b in zip([1,2,3],[1,2,3])]

output:

[(1+4j), (2+5j), (3+6j)]

ReferenceURL : https://stackoverflow.com/questions/2598734/numpy-creating-a-complex-array-from-2-real-ones

반응형