Подтвердить что ты не робот

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

Ответ 1

Это похоже на то, что вы хотите:

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]

PS: если вы хотите сохранить память (без промежуточного массива):

result = 1j*Data[...,1]; result += Data[...,0]
Решение

devS 'также выполняется быстро.

Ответ 2

Там, конечно, довольно очевидно:

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

Ответ 3

Если ваши реальные и мнимые части - это срезы вдоль последнего измерения, и ваш массив смежен вдоль последнего измерения, вы можете просто сделать

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), похоже, работает в большинстве случаев.

Ответ 4

Это то, что вы ищете:

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

Ответ 5

Я начинаю python, так что это может быть не самый эффективный метод, но, если я правильно понял цель вопроса, шаги, перечисленные ниже, работали для меня.

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

Ответ 6

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)

Ответ 7

Это сработало для меня:

ввод:

from scipy import *

array([[1,2],[3,2]]).astype(complex)

выход:

array([[ 1.+0.j, 2.+0.j], 
       [ 3.+0.j, 2.+0.j]])

Ответ 8

Если вы действительно хотите повысить производительность (с большими массивами), можно использовать numexpr, который использует преимущества нескольких ядер.

Настроить:

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

С помощью 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)

По сравнению с быстрым методом numpy:

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