8 Soru: Numpy: 2 gerçek olandan karmaşık bir dizi oluşturma?

tarafından oluşturulan soru Wed, Sep 5, 2012 12:00 AM

Yemin ederim ki bu kadar kolay olmalı ... Neden olmasın? : (

Aslında, aynı dizinin 2 bölümünü karmaşık bir dizi yapmak için birleştirmek istiyorum:

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

Bunlar işe yaramıyor:

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

Bir şey mi eksik? Numpy, karmaşık sayılar üzerinde dizi işlevi yapmaktan hoşlanmıyor mu? İşte hata:

 
TypeError: only length-1 arrays can be converted to Python scalars
    
52
8 Yanıtlar                              8                         

Bu istediğinizi yapar gibi görünüyor:

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

İşte başka bir çözüm:

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

Ve bir başka basit çözüm:

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

PS : Belleği kaydetmek istiyorsanız (ara dizi yok):

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

devS'nin aşağıdaki çözümü de hızlı.

    
63
2017-06-11 05: 09: 07Z
  1. Aynı hatadan korkuyorum: TypeError: yalnızca uzunluk-1 dizileri Python Scalar'lara dönüştürülebilir
    2010-04-08 09: 42: 18Z
  2. @ Duncan: Testi yaptıktan sonra orijinal cevabı güncelledim. Şimdi çalışıyor gibi görünüyor.
    2010-04-08 09: 43: 04Z
  3. çok işe yarıyor. Gerçi çok yavaş (beklediğiniz gibi - gerçekten huzursuz bir işlev olmadığından), döngü başına şimdi 0.1 yerine 5 saniye alıyor
    2010-04-08 09: 45: 57Z
  4. @ Duncan: Başka iki çözüm daha ekledim: zaman ayırmaya değer olabilir. Bu sizin için işe yararsa, lütfen cevabı yukarı kaldırın!
    2010-04-08 09: 52: 47Z
  5. Mükemmel ikisi de çok daha hızlıdır :)
    2010-04-08 10: 01: 53Z

Elbette oldukça belirgin olanı var:

 
Data[...,0] + 1j * Data[...,1]
    
35
2015-09-01 14: 10: 37Z
  1. Ayrıca Data.view(complex)
    2012-09-05 21: 40: 09Z

Gerçek ve hayali bölümleriniz son boyuttaki dilimlerse ve diziniz son boyut boyunca bitişikse, yalnızca yapabilirsiniz

 
A.view(dtype=np.complex128)

Tek duyarlıklı yüzdürme kullanıyorsanız, bu

 
A.view(dtype=np.complex64)

İşte daha eksiksiz bir örnek

 
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)

Dökümden kalan ekstra boyuttan kurtulmak istiyorsanız, bunun gibi bir şey yapabilirsiniz

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

Bu çalışır çünkü bellekte karmaşık bir sayı gerçekten iki kayan nokta sayısıdır. Birincisi gerçek kısmı, ikincisi ise hayali kısmı temsil eder. Dizinin görüntüleme yöntemi, bitişik iki kayan nokta değerini tek bir karmaşık sayı olarak değerlendirmek istediğinizi yansıtmak için dizinin türünü değiştirir ve boyutu buna göre günceller.

Bu yöntem, dizideki herhangi bir değeri kopyalamaz veya yeni hesaplamalar gerçekleştirmez; tek yaptığı, aynı bellek bloğunu farklı şekilde görüntüleyen yeni bir dizi nesnesi oluşturmaktır. Bu sayede bu işlem çok değer kopyalamayı gerektiren her şeyden daha hızlı gerçekleştirilebilir. Ayrıca, karmaşık değerli dizide yapılan herhangi bir değişikliğin, gerçek ve hayali bölümlerle dizide yansıtılacağı anlamına gelir.

Ayrıca, cast türünden hemen sonra orada bulunan fazla ekseni kaldırırsanız, orijinal diziyi kurtarmak biraz daha zor olabilir. A_comp[...,np.newaxis].view(np.float64) gibi şeyler şu anda çalışmıyor, çünkü bu yazı itibariyle NumPy, dizinin bu olduğunu algılamıyor.Yeni eksen eklendiğinde y hala C-bitişiktir. bu konuya bakın.  A_comp.view(np.float64).reshape(A.shape), ancak çoğu durumda çalışıyor gibi görünüyor.

    
20
2014-04-20 03: 42: 12Z
  1. + 1: Yöntemin sınırlamalarının çok net bir açıklaması. Açıkça başka bir sınırlama (A_comp ve A arasında paylaşılan hafıza) ve ayrıca bu yöntemin (hız) bir avantajını eklemek isteyebilirsiniz.
    2014-04-13 04: 14: 39Z
  2. @ EOL Teşekkürler. Cevabı buna göre güncelledim.
    2014-04-20 03: 46: 39Z

Aradığınız şey budur:

 
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
2014-01-06 20: 39: 43Z
  1. Bu, Pierre GM'ler veya benimki gibi önceki cevapların yalnızca bir kopyasıdır: Bunun tek etkisinin insanların katma değerli bir değere zaman ayırması olduğunu düşünüyorum (örneğin ötesinde) ), bu yüzden silmenizi öneririm.
    2017-02-14 11: 55: 59Z

Python acemi olduğum için bu en etkili yöntem olmayabilir, ancak sorunun amacını doğru anlarsam, aşağıda listelenen adımlar benim için çalıştı.

 
>>> 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
2014-04-13 04: 11: 41Z
  1. İlginç bir fikir. Bununla birlikte, soru Data[:,:,:,0] ve Data[:,:,:,1]’un birleştirilmesiyle ilgilidir (a’unuzdan daha karmaşık). Ayrıca, zeros() kullanmak yerine, daha hızlı ve daha uygun olan empty()'u kullanmalısınız.
    2014-01-29 22: 35: 21Z
  2. Onu Data […, 0] + 1j * Data […, 1] çözümü ile karşılaştırdım. Data = random.rand (100,100,1000,2), c = sıfır (a.shape [: - 1], dtype = karmaşık); c.real = Data [..., 0]; c.imag = Veri [..., 1]; basit Veriden 2 kat daha hızlıdır […, 0] + 1j * Veriler […, 1]. Şaşırtıcı bir şekilde, sıfır yerine boş kullanımın etkisi göz ardı edilebilirdi.
    2014-02-06 08: 51: 15Z
  3. + 1. Not: Son cevabımın bir değişkeni ile aynı hızı alıyorum: result = 1j*Data[...,1]; result += Data[...,0] Bununla birlikte, tek bir formül kullanılmadığında, bu cevap daha doğaldır.
    2014-02-07 13: 19: 13Z
  4. Bence en iyi cevap bu çünkü kodu okurken niyet belli; Eric'in yanıtları, işlevsel olarak doğru olsa da, kodu okurken daha az açıktır.
    2019-03-12 09: 58: 58Z
 
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)
    
3
2017-06-11 05: 12: 06Z

Gerçekten performans göstermek istiyorsanız (büyük dizilerle), numexpr , birden fazla çekirdekten yararlanan kullanılabilir.

Kurulum:

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

numexpr ile:

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

Hızlı numpy yöntemi ile karşılaştırıldığında:

 
>>> %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
2018-08-15 12: 45: 30Z

Bu benim için işe yaradı:

girişi:

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

çıktı:

 
[(1+4j), (2+5j), (3+6j)]
    
- 1
2019-03-23 ​​20: 11: 20Z
  1. - 1, bu hayali bölümü sıfıra eşit bırakır
    2014-01-28 15: 05: 01Z
  2. Güncellenmiş uygulamayı kontrol edin.
    2019-03-26 12: 05: 26Z
kaynak yerleştirildi İşte