The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Use scipy.spatial.KDTree to index points and find their nearest neighbors, or to answer related radius and pair-search questions. The usual workflow is to build a tree from an array shaped (n, m), then call query with one or more points whose final coordinate dimension is also m. The right method and settings depend on whether you need nearest ranks, all points within a radius, or a speed advantage over a direct distance calculation.
Build a KDTree from your points
A KDTree indexes n points in m-dimensional coordinate space. Pass an array whose rows are points and whose columns are coordinates:
import numpy as np
from scipy.spatial import KDTree
data = np.array([
[0.0, 0.0],
[1.0, 1.0],
[3.0, 2.0],
])
tree = KDTree(data)
Here, data.shape is (3, 2): three indexed points, each with two coordinates. For construction behavior and options, see the SciPy KDTree reference.
Keep the indexed data unchanged, or copy it
By default, copy_data=False. If SciPy can use the input array without copying it, changing that array after tree construction can corrupt search results. If the array may be modified elsewhere, construct the tree with copy_data=True so the tree keeps its own copy.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
Construction settings
The current constructor includes leafsize=10, compact_nodes=True, copy_data=False, balanced_tree=True, and boxsize=None, in addition to the data argument. leafsize sets the point count at which the algorithm switches to brute-force work within a leaf. These options affect tree organization and build/query tradeoffs; there is no universally best setting established by the API reference.
Find the nearest point with query
Call query with a point or an array of points. It returns a pair (d, i): distances in d and indices into the tree’s data in i.
point = [0.8, 0.9]
distance, index = tree.query(point)
nearest_point = tree.data[index]
With the default k=1, this requests the nearest neighbor. For a single query, the returned distance and index are scalars; for arrays of query points, their shape follows the query shape, with the neighbor dimension squeezed when k=1. If downstream code expects a consistent neighbor axis, account for that shape change or request ranks explicitly.
Rank #2
Request several neighbors or specific ranks
Set k to an integer to request neighbor ranks through that value. For example, k=3 requests the first, second, and third nearest neighbors. You can also pass a sequence of ranks, such as k=[1, 3], to return only the first and third nearest neighbors. Results are ordered nearest first among the requested ranks.
distances, indices = tree.query(point, k=3)
third_distance, third_index = tree.query(point, k=[3])
In the first call, each result covers three neighbor ranks. In the second, the requested rank is just the third neighbor.
Choose the distance norm with p
The p parameter selects a Minkowski distance in coordinate space: p=1 is Manhattan distance, p=2 is Euclidean distance, and p=np.inf is the maximum coordinate difference. Use the norm that matches the meaning of distance in your application. Very large finite values of p can overflow.
Use approximate search only when its tolerance fits
The default eps=0.0 requests exact nearest-neighbor results. A nonnegative eps enables approximate search: SciPy guarantees that the returned kth neighbor is no farther than (1 + eps) times the true kth-neighbor distance. This is a distance guarantee, not a promise of a particular speedup; choose a tolerance your application can accept and measure its effect on representative queries.
Limit results by distance and handle missing neighbors
distance_upper_bound limits eligible results. If a requested neighbor is not found within that bound, SciPy returns an infinite distance and the index tree.n. Treat these as paired missing-result markers; do not use the index to access data[tree.n].
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
distances, indices = tree.query(
point,
k=3,
distance_upper_bound=1.0,
)
found = np.isfinite(distances)
valid_indices = indices[found]
For vectorized code, use the distance marker to mask both arrays before gathering points or doing further calculations.
Use multiple CPU threads when appropriate
workers controls parallel processing for a query call. It defaults to 1; workers=-1 requests all CPU threads. Parallelism can help with batches of queries, but its benefit depends on the workload. The current SciPy query reference documents workers as added in SciPy 1.6.0; older examples using n_jobs are obsolete, as that name was removed in SciPy 1.9.0. See the KDTree query reference.
Choose the query method that matches the question
Nearest-neighbor lookup is only one kind of spatial query. Use the method that reflects the set of points and relationship you want:
| Question | Method | What it returns |
|---|---|---|
| Which indexed points are nearest to each query point? | query |
The requested nearest-neighbor ranks, with distances and indices. |
| Which indexed points lie within a radius of external query point(s)? | query_ball_point |
Indices of points within the radius for each query point. |
| Which pairs within one indexed set are within a radius? | query_pairs |
Pairs of points from the same tree that are within the radius. See the query_pairs reference. |
| Which points in one tree are within a radius of points in another tree? | query_ball_tree |
Cross-tree neighbors within the radius. See the query_ball_tree reference. |
Use query_ball_point for radius searches around a point or batch of query points. The current KDTree query reference documents query for nearest ranks; the earlier k=None radius-query behavior was removed in SciPy 1.9.0.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
When is KDTree faster than brute force?
A KDTree prunes search by organizing points into axis-aligned regions, but that does not guarantee a speed advantage for every dimension, point distribution, or query workload. SciPy’s KDTree documentation warns: “For large dimensions (20 is already large) do not expect this to run significantly faster than brute force.” Treat that as the library’s caution, not a universal cutoff or a benchmark result.
Compare against direct distance calculations using the data and query pattern you actually expect. Include the cost of building the tree, especially when you will make few queries, and measure representative batches rather than assuming that the tree is always faster. Relevant factors include:
- Number of indexed points and dimensionality.
- Point distribution and clustering.
- Tree build cost versus the number of queries.
- Whether exact results or an
epstolerance is acceptable. - Distance norm and any distance cutoff.
- Memory use and whether the input data can be safely shared.
- Measured latency for the intended workload.
The SciPy references provide no general speedup figure that applies across machines and datasets, so timing your workload is the useful comparison.
Coordinates must match the distance you intend
KDTree’s documented p options measure Minkowski distance in the coordinates you supply. If those coordinates are latitude and longitude, ordinary Euclidean distance in degrees may not represent the geographic distance your application needs. Transform coordinates appropriately or use a method designed for the intended geometry; the KDTree API reference alone does not prescribe a geodesic workflow.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsKDTree and cKDTree in current SciPy
The current SciPy references document both KDTree and cKDTree query APIs. Follow the reference for the class and SciPy version used by your project, particularly for parameter names: use workers, not the removed n_jobs. The cited API documentation does not establish a universal performance winner between the two classes, so benchmark the option you plan to deploy rather than relying on a blanket speed claim.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




