Numpy'deki düzleştirme ve ravel işlevleri arasındaki fark nedir?


292
import numpy as np
y = np.array(((1,2,3),(4,5,6),(7,8,9)))
OUTPUT:
print(y.flatten())
[1   2   3   4   5   6   7   8   9]
print(y.ravel())
[1   2   3   4   5   6   7   8   9]

Her iki işlev de aynı listeyi döndürür. O zaman aynı işi yapan iki farklı fonksiyona ihtiyaç vardır.


14
Ravel genellikle mevcut diziye bir görünüm döndürür (bazen bir kopyasını döndürür). Düzleştir yeni bir dizi döndürür.
Alex


1
İşte ince farkın pratik bir gösterimi.
prosti

Öyleyse, birisi bir diziyi düzleştirmenin daha iyi olduğu ve ne zaman ravel yapacağı konusunda bir örnek verebilir mi?
Aleksandar

Yanıtlar:


371

Mevcut API şudur:

  • flatten her zaman bir kopyasını döndürür.
  • ravelmümkün olduğunda orijinal dizinin bir görünümünü döndürür. Bu yazdırılan çıktıda görünmez, ancak ravel tarafından döndürülen diziyi değiştirirseniz, orijinal dizideki girdileri değiştirebilir. Düzleştirmeyle döndürülen bir dizideki girdileri değiştirirseniz, bu asla gerçekleşmez. Hiçbir bellek kopyalanmadığından ravel genellikle daha hızlı olur, ancak döndürdüğü diziyi değiştirme konusunda daha dikkatli olmanız gerekir.
  • reshape((-1,)) Her zaman bitişik bir dizi elde etmediğiniz anlamına gelse bile, dizinin adımlarının izin verdiği her durumda bir görünüm alır.

30
NumPy geliştiricilerinin neden bir parametre copy = [True, False] ile bir işleve bağlı kalmadıklarına dair bir fikir var mı?
Franck Dernoncourt

41
Geri uyumluluk garantileri bazen böyle garip şeylerin olmasına neden olur. Örneğin: kısa bir süre önce (1.10'da) numpy geliştiricileri, ravel'in bitişik bir dizi (C uzantıları yazarken çok önemli bir özellik) döndüreceği konusunda önceden örtük bir garanti eklediler, bu yüzden şimdi API önlemek a.flatten()için bir kopya a.ravel()almaktır. çoğu kopya, ancak yine de döndürülen dizinin bitişik olduğunu garanti eder ve dizinin a.reshape((-1,))adımlarının izin verdiği her zaman gerçekten bir görünüm elde etmek , her zaman bitişik bir dizi almamanız anlamına gelse bile.
IanH

4
@Hossein IanH açıkladı: ravelbitişik bir diziyi garanti eder ve bu yüzden bir görünüm döndürdüğü garanti edilmez; reshapeher zaman bir görünüm döndürür ve bu nedenle bitişik bir dizi döndürdüğü garanti edilmez.
iled

4
@Hossein Bu tamamen yeni bir soru olurdu. Kısaca, bitişik bir bellek alanına okumak ve yazmak çok daha hızlıdır. Burada SO ile ilgili birkaç soru ve cevap var ( burada güzel bir örnek ), başka sorularınız varsa yeni bir soru açmaktan çekinmeyin.
iled

2
reshape(-1)eşdeğerreshape((-1,))
Tom Pohl

53

As açıkladı Burada bir temel fark şudur:

  • flatten ndarray nesnesinin bir yöntemidir ve bu nedenle yalnızca gerçek numpy dizileri için çağrılabilir.

  • ravel kütüphane düzeyinde bir işlevdir ve bu nedenle başarıyla ayrıştırılabilen herhangi bir nesne üzerinde çağrılabilir.

Örneğin ravel, flattenbu tür bir nesne için kullanılamazken , bir ndarray listesi üzerinde çalışacaktır .

@IanH ayrıca cevabında hafıza işlemeyle ilgili önemli farklara dikkat çekiyor.


4
ravel () hakkında bilgi için ndarray
teşekkürler

Sadece dizi listeleri değil, aynı zamanda liste listeleri :)
timtody

15

İşlevler için doğru ad alanı:

Her iki işlev de yeni bellek yapılarına işaret eden düzleştirilmiş 1D dizileri döndürür.

import numpy
a = numpy.array([[1,2],[3,4]])

r = numpy.ravel(a)
f = numpy.ndarray.flatten(a)  

print(id(a))
print(id(r))
print(id(f))

print(r)
print(f)

print("\nbase r:", r.base)
print("\nbase f:", f.base)

---returns---
140541099429760
140541099471056
140541099473216

[1 2 3 4]
[1 2 3 4]

base r: [[1 2]
 [3 4]]

base f: None

Yukarıdaki örnekte:

  • sonuçların hafıza konumları farklıdır,
  • sonuçlar aynı görünüyor
  • flatten bir kopyasını döndürür
  • ravel bir görüşe dönecekti.

Bir şeyin kopya olup olmadığını nasıl kontrol ederiz? 'Nin .baseözniteliğini kullanarak ndarray. Bir görünümse, taban orijinal dizi olacaktır; bu bir kopya ise, temel olacaktır None.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.