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
Ответы
Ответ 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)