Cải thiện bài viết
Lưu bài viết
Nói một cách đơn giản, khoảng cách Euclide là ngắn nhất giữa 2 điểm bất kể kích thước. Trong bài viết này để tìm khoảng cách Euclide, chúng tôi sẽ sử dụng thư viện Numpy. Thư viện này được sử dụng để điều khiển mảng đa chiều một cách rất hiệu quả. Hãy để thảo luận về một vài cách để tìm khoảng cách Euclide của Thư viện Numpy.
Phương pháp số 1: Sử dụng linalg.norm [] & nbsp;
Python3
2.236067977499791
2.236067977499792
2.236067977499793
2.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499798
2.236067977499797
dist = numpy.linalg.norm[a-b]
0dist = numpy.linalg.norm[a-b]
1dist = numpy.linalg.norm[a-b]
22.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499796
2.236067977499797
2.236067977499796
dist = numpy.linalg.norm[a-b]
1sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
12.236067977499794
sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
3sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
4 sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
5sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
6sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
7Output:
2.23606797749979
Phương pháp số 2: Sử dụng dot [] & nbsp;
Python3
2.236067977499791
2.236067977499792
2.236067977499793
2.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499798
2.236067977499797
dist = numpy.linalg.norm[a-b]
0dist = numpy.linalg.norm[a-b]
1dist = numpy.linalg.norm[a-b]
22.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499796
2.236067977499797
2.236067977499796
dist = numpy.linalg.norm[a-b]
1sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
12.236067977499794
sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
3sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
4 sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
5Phương pháp số 2: Sử dụng dot [] & nbsp;
sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
6def distance[pointA, pointB, _norm=np.linalg.norm]:
return _norm[pointA - pointB]
7Output:
2.23606797749979
8>>> dis.dis[distance]
2 0 LOAD_GLOBAL 0 [np]
2 LOAD_ATTR 1 [linalg]
4 LOAD_ATTR 2 [norm]
6 LOAD_FAST 0 [pointA]
8 LOAD_FAST 1 [pointB]
10 BINARY_SUBTRACT
12 CALL_FUNCTION 1
14 STORE_FAST 2 [dist]
3 16 LOAD_FAST 2 [dist]
18 RETURN_VALUE
2.23606797749979
4 2.23606797749979
3
4 sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
2 def distance[pointA, pointB, _norm=np.linalg.norm]:
return _norm[pointA - pointB]
Python3
2.236067977499791
2.236067977499792
2.236067977499793
2.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499798
2.236067977499797
dist = numpy.linalg.norm[a-b]
0dist = numpy.linalg.norm[a-b]
1dist = numpy.linalg.norm[a-b]
22.236067977499794
2.236067977499795
2.236067977499796
2.236067977499797
2.236067977499796
2.236067977499797
2.236067977499796
dist = numpy.linalg.norm[a-b]
1sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
12.236067977499794
sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
3sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
4 sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
5sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
6def distance[pointA, pointB, _norm=np.linalg.norm]:
return _norm[pointA - pointB]
7Output:
2.23606797749979
Tôi muốn giải thích về câu trả lời đơn giản với các ghi chú hiệu suất khác nhau. np.linalg.norm có lẽ sẽ làm nhiều hơn bạn cần:
dist = numpy.linalg.norm[a-b]
Đầu tiên - chức năng này được thiết kế để hoạt động qua danh sách và trả về tất cả các giá trị, ví dụ: Để so sánh khoảng cách từ
2.2360679774997907 với tập hợp các điểm
2.2360679774997908:
sP = set[points]
pA = point
distances = np.linalg.norm[sP - pA, ord=2, axis=1.] # 'distances' is a list
Hãy nhớ một số điều:
- Các cuộc gọi chức năng Python rất tốn kém.
- [Thường xuyên] Python không tra cứu tên bộ đệm.
Vì thế
def distance[pointA, pointB]:
dist = np.linalg.norm[pointA - pointB]
return dist
không phải là ngây thơ như vẻ ngoài của nó.
>>> dis.dis[distance]
2 0 LOAD_GLOBAL 0 [np]
2 LOAD_ATTR 1 [linalg]
4 LOAD_ATTR 2 [norm]
6 LOAD_FAST 0 [pointA]
8 LOAD_FAST 1 [pointB]
10 BINARY_SUBTRACT
12 CALL_FUNCTION 1
14 STORE_FAST 2 [dist]
3 16 LOAD_FAST 2 [dist]
18 RETURN_VALUE
Đầu tiên - mỗi khi chúng tôi gọi nó, chúng tôi phải tìm kiếm "NP" toàn cầu, một bộ tra cứu phạm vi cho "Linalg" và tìm kiếm một phạm vi cho "định mức", và chi phí đơn thuần gọi chức năng có thể tương đương với hàng chục Python hướng dẫn.
Cuối cùng, chúng tôi đã lãng phí hai hoạt động để lưu trữ kết quả và tải lại để trả lại ...
Pass đầu tiên khi cải tiến: Tra cứu nhanh hơn, bỏ qua cửa hàng
def distance[pointA, pointB, _norm=np.linalg.norm]:
return _norm[pointA - pointB]
Chúng tôi nhận được sự hợp lý hơn nhiều:
>>> dis.dis[distance]
2 0 LOAD_FAST 2 [_norm]
2 LOAD_FAST 0 [pointA]
4 LOAD_FAST 1 [pointB]
6 BINARY_SUBTRACT
8 CALL_FUNCTION 1
10 RETURN_VALUE
Mặc dù vậy, các cuộc gọi trên đầu vẫn là một số công việc. Và bạn sẽ muốn thực hiện các điểm chuẩn để xác định xem bạn có thể tự mình làm toán tốt hơn không:
def distance[pointA, pointB]:
return [
[[pointA.x - pointB.x] ** 2] +
[[pointA.y - pointB.y] ** 2] +
[[pointA.z - pointB.z] ** 2]
] ** 0.5 # fast sqrt
Trên một số nền tảng,
2.2360679774997909 nhanh hơn
2.2360679774997910. Số dặm của bạn có thể khác nhau.
**** Ghi chú hiệu suất nâng cao.
Tại sao bạn tính khoảng cách? Nếu mục đích duy nhất là hiển thị nó,
2.236067977499790
di chuyển theo. Nhưng nếu bạn đang so sánh khoảng cách, kiểm tra phạm vi, v.v., tôi muốn thêm một số quan sát hiệu suất hữu ích.
Hãy để Lừa lấy hai trường hợp: Sắp xếp theo khoảng cách hoặc loại bỏ danh sách đến các mục đáp ứng hạn chế phạm vi.
2.236067977499791
Điều đầu tiên chúng ta cần nhớ là chúng ta đang sử dụng Pythagoras để tính khoảng cách [
2.2360679774997911] vì vậy chúng ta thực hiện rất nhiều cuộc gọi
2.2360679774997912. Toán 101:
2.236067977499792
Nói tóm lại: Cho đến khi chúng tôi thực sự yêu cầu khoảng cách trong một đơn vị x thay vì x^2, chúng tôi có thể loại bỏ phần khó nhất của các tính toán.
2.236067977499793
Tuyệt vời, cả hai chức năng không có bất kỳ rễ vuông đắt tiền nào. Điều đó sẽ nhanh hơn nhiều, nhưng trước khi bạn đi xa hơn, hãy tự mình kiểm tra: Tại sao sort_things_by_distance cần từ chối trách nhiệm "ngây thơ" cả hai lần ở trên? Trả lời ở phía dưới [*A1].
Chúng ta có thể cải thiện in_range bằng cách chuyển đổi nó thành một trình tạo:
2.236067977499794
Điều này đặc biệt có lợi ích nếu bạn đang làm một cái gì đó như:
2.236067977499795
Nhưng nếu điều tiếp theo bạn sẽ làm đòi hỏi một khoảng cách,
2.236067977499796
Xem xét các bộ dữ liệu năng suất:
2.236067977499797
Điều này có thể đặc biệt hữu ích nếu bạn có thể kiểm tra phạm vi ['Tìm những thứ gần X và trong NM của Y', vì bạn không phải tính toán khoảng cách nữa].
Nhưng nếu chúng ta đang tìm kiếm một danh sách thực sự lớn của
2.2360679774997913 và chúng ta dự đoán rất nhiều trong số họ không được xem xét?
Thực sự có một tối ưu hóa rất đơn giản:
2.236067977499798
Liệu điều này có hữu ích hay không sẽ phụ thuộc vào kích thước của 'những thứ'.
2.236067977499799
Và một lần nữa, hãy xem xét năng suất dist_sq. Ví dụ hotdog của chúng tôi sau đó trở thành:
2.236067977499790
.