Apa perbedaan antara fungsi rata dan berlepasan di numpy?

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]

Kedua fungsi mengembalikan daftar yang sama. Lalu apa perlunya dua fungsi berbeda melakukan pekerjaan yang sama.

cryptomanic
sumber
14
Ravel biasanya mengembalikan tampilan ke array yang ada (kadang-kadang mengembalikan salinan). Ratakan kembali array baru.
Alex
1
Berikut ini adalah peragaan praktis perbedaan tipis.
prosti
Jadi bisakah seseorang memberi contoh kapan lebih baik meratakan sebuah array dan kapan harus meng-overlaynya?
Aleksandar

Jawaban:

371

API saat ini adalah:

  • flatten selalu mengembalikan salinan.
  • ravelmengembalikan tampilan array asli jika memungkinkan. Ini tidak terlihat dalam output yang dicetak, tetapi jika Anda memodifikasi array yang dikembalikan oleh ravel, itu dapat memodifikasi entri dalam array asli. Jika Anda memodifikasi entri dalam array yang dikembalikan dari rata ini tidak akan pernah terjadi. ravel akan lebih cepat karena tidak ada memori yang disalin, tetapi Anda harus lebih berhati-hati dalam memodifikasi array yang dikembalikannya.
  • reshape((-1,)) mendapat tampilan setiap kali langkah array memungkinkan, bahkan jika itu berarti Anda tidak selalu mendapatkan array yang berdekatan.
IanH
sumber
30
Tahu mengapa pengembang NumPy tidak menempel satu fungsi dengan beberapa parameter salin = [Benar, Salah]?
Franck Dernoncourt
41
Jaminan Backcompat terkadang menyebabkan hal-hal aneh seperti ini terjadi. Sebagai contoh: pengembang numpy baru-baru ini (di 1.10) menambahkan jaminan implisit sebelumnya bahwa ravel akan mengembalikan array yang berdekatan (properti yang sangat penting saat menulis ekstensi C), jadi sekarang API akan a.flatten()mendapatkan salinan untuk memastikan, a.ravel()untuk menghindari sebagian besar salinan tetapi masih menjamin bahwa array yang dikembalikan bersebelahan, dan a.reshape((-1,))untuk benar-benar mendapatkan tampilan setiap kali langkah array memungkinkan bahkan jika itu berarti Anda tidak selalu mendapatkan array yang berdekatan.
IanH
4
@Hossein IanH menjelaskannya: ravelmenjamin susunan yang berdekatan, dan karenanya tidak dijamin akan mengembalikan tampilan; reshapeselalu mengembalikan tampilan, dan karenanya tidak dijamin akan mengembalikan array yang berdekatan.
iled
4
@ Hussein Itu akan menjadi pertanyaan yang sama sekali baru. Secara singkat, jauh lebih cepat untuk membaca dan menulis ke ruang memori yang berdekatan. Ada beberapa pertanyaan dan jawaban di sini di SO ( contoh bagus di sini ), jangan ragu untuk membuka yang baru jika Anda memiliki pertanyaan lebih lanjut.
iled
2
reshape(-1)setara denganreshape((-1,))
Tom Pohl
53

Sebagaimana dijelaskan di sini, perbedaan utama adalah:

  • flatten adalah metode objek ndarray dan karenanya hanya dapat dipanggil untuk array numpy yang sebenarnya.

  • ravel adalah fungsi tingkat perpustakaan dan karenanya dapat dipanggil pada objek apa pun yang berhasil diurai.

Misalnya ravelakan bekerja pada daftar ndarrays, sementara flattentidak tersedia untuk jenis objek itu.

@IH juga menunjukkan perbedaan penting dengan penanganan memori dalam jawabannya.

Bryan P
sumber
4
thx untuk info tentang ravel () yang bekerja pada daftar ndarray's
javadba
Tidak hanya daftar array tetapi juga daftar daftar :)
timtody
15

Berikut adalah namespace yang benar untuk fungsinya:

Kedua fungsi mengembalikan susunan 1D yang rata yang menunjuk ke struktur memori yang baru.

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

Dalam contoh atas:

  • lokasi memori hasil berbeda,
  • hasilnya terlihat sama
  • rata akan mengembalikan salinan
  • Ravel akan mengembalikan tampilan.

Bagaimana kami memeriksa apakah ada salinannya? Menggunakan .baseatribut ndarray. Jika ini adalah tampilan, basis akan menjadi array asli; jika itu adalah salinan, basisnya adalah None.

prosti
sumber