Saya memiliki dua poin dalam 3D:
(xa, ya, za)
(xb, yb, zb)
Dan saya ingin menghitung jarak:
dist = sqrt((xa-xb)^2 + (ya-yb)^2 + (za-zb)^2)
Apa cara terbaik untuk melakukan ini dengan NumPy, atau dengan Python secara umum? Saya sudah:
import numpy
a = numpy.array((xa ,ya, za))
b = numpy.array((xb, yb, zb))
python
numpy
euclidean-distance
Nathan Fellman
sumber
sumber
Ada fungsi untuk itu di SciPy. Ini disebut Euclidean .
Contoh:
sumber
Bagi siapa pun yang tertarik menghitung banyak jarak sekaligus, saya telah melakukan sedikit perbandingan menggunakan perfplot (proyek kecil saya).
Saran pertama adalah mengatur data Anda sedemikian rupa sehingga array memiliki dimensi
(3, n)
(dan jelas bersebelahan C). Jika menambahkan terjadi di dimensi pertama yang berdekatan, segala sesuatunya lebih cepat, dan tidak masalah jika Anda gunakansqrt-sum
denganaxis=0
,linalg.norm
denganaxis=0
, atauyang, dengan sedikit perbedaan, varian tercepat. (Itu benar-benar berlaku hanya untuk satu baris juga.)
Varian di mana Anda meringkas pada sumbu kedua
axis=1
,, semuanya jauh lebih lambat.Kode untuk mereproduksi plot:
sumber
i,i->
data
harus terlihat seperti?Saya ingin menguraikan jawaban sederhana dengan berbagai catatan kinerja. np.linalg.norm mungkin akan melakukan lebih dari yang Anda butuhkan:
Pertama - fungsi ini dirancang untuk mengerjakan daftar dan mengembalikan semua nilai, misalnya untuk membandingkan jarak dari
pA
ke set poinsP
:Ingat beberapa hal:
Begitu
tidak sesugu kelihatannya.
Pertama - setiap kali kita menyebutnya, kita harus melakukan pencarian global untuk "np", pencarian lingkup untuk "linalg" dan pencarian lingkup untuk "norma", dan overhead hanya memanggil fungsi dapat menyamakan dengan puluhan python instruksi.
Terakhir, kami membuang dua operasi untuk menyimpan hasilnya dan memuatnya kembali ...
Pass pertama pada peningkatan: membuat pencarian lebih cepat, lewati toko
Kami mendapatkan yang lebih efisien:
Fungsi panggilan overhead masih sejumlah pekerjaan, meskipun. Dan Anda ingin melakukan tolok ukur untuk menentukan apakah Anda bisa melakukan sendiri matematika dengan lebih baik:
Pada beberapa platform,
**0.5
lebih cepat daripadamath.sqrt
. Jarak tempuh Anda mungkin beragam.**** Catatan kinerja lanjutan.
Mengapa Anda menghitung jarak? Jika satu-satunya tujuan adalah untuk menampilkannya,
berjalan terus. Tetapi jika Anda membandingkan jarak, melakukan pemeriksaan jarak, dll., Saya ingin menambahkan beberapa pengamatan kinerja yang bermanfaat.
Mari kita ambil dua kasing: mengurutkan berdasarkan jarak atau memilah daftar item yang memenuhi batasan jangkauan.
Hal pertama yang perlu kita ingat adalah bahwa kita menggunakan Pythagoras untuk menghitung jarak (
dist = sqrt(x^2 + y^2 + z^2)
) jadi kita membuat banyaksqrt
panggilan. Matematika 101:Singkatnya: sampai kita benar-benar membutuhkan jarak dalam satuan X daripada X ^ 2, kita dapat menghilangkan bagian tersulit dari perhitungan.
Hebat, kedua fungsi tidak lagi melakukan akar kuadrat mahal. Itu akan jauh lebih cepat. Kami juga dapat meningkatkan in_range dengan mengonversinya menjadi generator:
Ini terutama memiliki manfaat jika Anda melakukan sesuatu seperti:
Tetapi jika hal berikutnya yang akan Anda lakukan membutuhkan jarak,
pertimbangkan menghasilkan tupel:
Ini bisa sangat berguna jika Anda dapat melakukan serangkaian cek ('temukan hal-hal yang mendekati X dan dalam Nm dari Y', karena Anda tidak perlu menghitung jarak lagi).
Tetapi bagaimana jika kita mencari daftar yang sangat besar
things
dan kita mengantisipasi banyak dari mereka tidak layak dipertimbangkan?Sebenarnya ada optimasi yang sangat sederhana:
Apakah ini berguna akan tergantung pada ukuran 'barang'.
Dan lagi, pertimbangkan untuk menghasilkan dist_sq. Contoh hotdog kami kemudian menjadi:
sumber
pointZ
yang tidak ada. Saya pikir yang Anda maksud adalah dua titik dalam ruang tiga dimensi dan saya mengeditnya. Jika saya salah, tolong beri tahu saya.Contoh lain dari metode pemecahan masalah ini :
sumber
norm = lambda x: N.sqrt(N.square(x).sum())
;norm(x-y)
numpy.linalg.norm(x-y)
Dimulai
Python 3.8
,math
modul secara langsung menyediakandist
fungsi, yang mengembalikan jarak euclidean antara dua titik (diberikan sebagai tupel atau daftar koordinat):Dan jika Anda bekerja dengan daftar:
sumber
Itu bisa dilakukan seperti berikut ini. Saya tidak tahu seberapa cepat itu, tetapi tidak menggunakan NumPy.
sumber
for a, b in zip(a, b)
. Tapi tidak ada yang berguna.Saya menemukan fungsi 'dist' di matplotlib.mlab, tapi saya rasa itu tidak cukup berguna.
Saya mempostingnya di sini hanya untuk referensi.
sumber
Saya suka
np.dot
(produk titik):sumber
Satu kalimat bagus:
Namun, jika kecepatan menjadi perhatian saya akan merekomendasikan bereksperimen pada mesin Anda. Saya telah menemukan bahwa menggunakan
math
perpustakaansqrt
dengan**
operator untuk kuadrat jauh lebih cepat pada mesin saya daripada solusi NumPy satu-liner.Saya menjalankan tes saya menggunakan program sederhana ini:
Di komputer saya,
math_calc_dist
berjalan lebih cepat daripadanumpy_calc_dist
: 1,5 detik versus 23,5 detik.Untuk mendapatkan perbedaan yang terukur antara
fastest_calc_dist
danmath_calc_dist
saya harus mencapaiTOTAL_LOCATIONS
6000. Kemudianfastest_calc_dist
butuh ~ 50 detik sementaramath_calc_dist
butuh ~ 60 detik.Anda juga dapat bereksperimen dengan
numpy.sqrt
dannumpy.square
meskipun keduanya lebih lambat darimath
alternatif di mesin saya.Tes saya dijalankan dengan Python 2.6.6.
sumber
scipy.spatial.distance.cdist(p1, p2).sum()
,. Hanya itu saja.numpy.linalg.norm(p1-p2).sum()
untuk mendapatkan jumlah antara setiap titik di p1 dan titik yang sesuai di p2 (yaitu tidak setiap titik di p1 ke setiap titik di p2). Dan jika Anda ingin setiap titik di p1 ke setiap titik di p2 dan tidak ingin menggunakan scipy seperti dalam komentar saya sebelumnya, maka Anda dapat menggunakan np.apply_along_axis bersama dengan numpy.linalg.norm untuk tetap melakukannya, jauh lebih cepat maka solusi "tercepat" Anda.Anda bisa mengurangi vektor dan kemudian produk dalam.
Mengikuti contoh Anda,
sumber
Memiliki
a
danb
seperti yang Anda tetapkan, Anda juga dapat menggunakan:sumber
Dengan Python 3.8, ini sangat mudah.
https://docs.python.org/3/library/math.html#math.dist
sumber
Berikut adalah beberapa kode ringkas untuk jarak Euclidean di Python yang diberikan dua titik yang direpresentasikan sebagai daftar dalam Python.
sumber
Sejak Python 3.8
Sejak Python 3.8
math
modul ini menyertakan fungsimath.dist()
.Lihat di sini https://docs.python.org/3.8/library/math.html#math.dist .
sumber
Hitung jarak Euclidean untuk ruang multidimensi:
sumber
sumber
sumber
Anda dapat dengan mudah menggunakan formula
yang sebenarnya tidak lebih dari menggunakan teorema Pythagoras untuk menghitung jarak, dengan menambahkan kuadrat Δx, Δy dan Δz dan me-rooting hasilnya.
sumber
Cari perbedaan dua matriks terlebih dahulu. Kemudian, terapkan elemen multiplikasi bijak dengan perintah gandakan numpy. Setelah itu, cari penjumlahan dari elemen yang bijak dikalikan matriks baru. Akhirnya, temukan akar kuadrat dari penjumlahan.
sumber
Anda berubah Daftar pertama yang array yang numpy dan melakukan seperti ini:
print(np.linalg.norm(np.array(a) - np.array(b)))
. Metode kedua langsung dari daftar python sebagai:print(np.linalg.norm(np.subtract(a,b)))
sumber