76

同じ配列の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
4

9 に答える 9

86

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

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

于 2010-04-08T09:38:22.977 に答える
51

もちろん、かなり明白なものがあります。

Data[...,0] + 1j * Data[...,1]
于 2012-09-05T19:34:07.863 に答える
28

実数部と虚数部が最後の次元に沿ったスライスであり、配列が最後の次元に沿って隣接している場合は、次のことができます。

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つの浮動小数点数にすぎないためです。1つ目は実数部を表し、2つ目は虚数部を表します。配列のviewメソッドは、配列のdtypeを変更して、2つの隣接する浮動小数点値を単一の複素数として扱い、それに応じて次元を更新することを反映します。

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

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

于 2014-02-24T18:51:09.783 に答える
18

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

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])
于 2014-01-06T17:09:09.373 に答える
15

私は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)
于 2013-10-28T18:48:12.443 に答える
4
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)
于 2017-03-12T06:47:56.560 に答える
0

(大きなアレイで)パフォーマンスを本当に発揮させたい場合は、複数のコアを利用する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)
于 2018-08-15T12:45:30.953 に答える
0

私は次の方法を使用します:

import numpy as np

real = np.ones((2, 3))
imag = 2*np.ones((2, 3))

complex = np.vectorize(complex)(real, imag)
# OR
complex = real + 1j*imag
于 2020-09-02T13:34:24.163 に答える
-1

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

入力:

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

出力:

[(1+4j), (2+5j), (3+6j)]
于 2011-07-18T19:08:27.107 に答える