web-dev-qa-db-ja.com

Numpy:2つの実際の配列から複雑な配列を作成しますか?

私はこれはとても簡単だと誓います...なぜそうではないのですか? :(

実際、同じ配列の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
53
Duncan Tait

これはあなたが望むことをするようです:

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のソリューションも高速です。

64
Eric O Lebigot

もちろん、かなり明白なことがあります:

Data[...,0] + 1j * Data[...,1]
35
Pierre GM

実部と虚部が最後の次元に沿ったスライスであり、配列が最後の次元に沿って連続している場合、次のようにできます。

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

これは、メモリ内の複素数が実際には2つの浮動小数点数であるためです。最初は実部を表し、2番目は虚部を表します。配列のviewメソッドは、2つの隣接する浮動小数点値を単一の複素数として扱い、それに応じて次元を更新することを反映するように配列のdtypeを変更します。

このメソッドは、配列の値をコピーしたり、新しい計算を実行したりすることはありません。同じメモリブロックを異なる方法で表示する新しい配列オブジェクトを作成するだけです。これにより、この操作は、値のコピーを伴うものよりも速くmuch実行できるようになります。また、複素数値配列で行われた変更は、実数部と虚数部を含む配列に反映されます。

また、型キャストの直後にある余分な軸を削除する場合、元の配列を回復するのは少し難しいかもしれません。この記事の執筆時点では、NumPyは新しい軸が追加されたときに配列がまだC連続であることを検出しないため、A_comp[...,np.newaxis].view(np.float64)のようなものは現在動作しません。 この問題 を参照してください。 A_comp.view(np.float64).reshape(A.shape)はほとんどの場合に機能するようです。

20
IanH

これはあなたが探しているものです:

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

私は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)
9
devS
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)

(大きな配列で)パフォーマンスを本当に引き出したい場合は、複数のコアを活用する 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)
0
jawknee

それは私のために働いた:

入力:

from scipy import *

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

出力:

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