Clustering Data Points
Clustering Data Points
DataPoint, Cluster, and ClusterCollection are a small, general-purpose
hierarchical-agglomerative-clustering toolkit bundled with Aspose.PDF FOSS for
Python. They are generic data-grouping primitives — a coordinate-and-label
point, a group of items, and a collection of groups — rather than a
PDF-specific document feature; nothing in this module reads or writes PDF
content itself. Use them when your own code needs to group numeric values
(for example, measurements you have already extracted from a document) into
clusters and summarize a cluster with its centroid.
Representing a Data Point
DataPoint pairs an identifying name with a value list of numeric
coordinates. Both are exposed as DataPoint.name and DataPoint.value after
construction.
Building and Copying Clusters
Cluster wraps an optional list of items into a single group. Cluster.count
reports how many items the cluster currently holds, Cluster.contains()
checks whether a given item is a member, and Cluster.clone() returns an
independent copy backed by its own item list. Cluster.empty() returns a
shared, singleton empty-cluster instance rather than allocating a new one on
every call.
Grouping Clusters in a Collection
ClusterCollection wraps an optional list of Cluster instances into a
single collection, giving you one object to pass around when a function needs
to accept or return more than one cluster at a time.
Calculating a Cluster Centroid
DataPoint.get_centroid() averages the coordinates of every data point in a
Cluster, position by position, and returns a new DataPoint representing
the centroid. Every point in the cluster must carry the same number of
dimensions in DataPoint.value for the average to be meaningful.
Tips and Best Practices
- Keep every
DataPoint.valuelist the same length within a cluster —DataPoint.get_centroid()averages coordinates position by position, so mismatched dimensions produce a misleading centroid. - Use
Cluster.empty()for a shared, singleton empty cluster instead of constructing a fresh empty cluster when you just need a placeholder value. - Call
Cluster.clone()before mutating a cluster you still need the original of elsewhere — cloning copies the item list rather than aliasing it. - Reach for
ClusterCollectionwhen a function needs to accept or return more than oneClusteras a single value. - These classes are generic utilities, not a PDF-parsing feature — pair them
with your own logic for producing the
DataPointvalues from document data.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
DataPoint.get_centroid() produces a centroid with an unexpected number of values | Data points in the cluster have DataPoint.value lists of different lengths | Ensure every DataPoint added to a Cluster has the same dimensionality |
Cluster.contains() returns False for a value you expect to be present | Membership is checked against the stored item objects directly, so two separately-constructed DataPoint instances with the same name and value are not automatically treated as equal by identity-based lookups | Reuse the same DataPoint instance, or compare by DataPoint.name and DataPoint.value before assuming membership |
| Mutating a cloned cluster also changes the original | Cluster.clone() was skipped and the same Cluster reference was shared instead of copied | Call Cluster.clone() first whenever a caller needs an independent copy |
FAQ
What is the difference between Cluster and ClusterCollection?
Cluster holds a list of items — typically DataPoint instances — that
belong to one group. ClusterCollection holds a list of Cluster objects:
it groups clusters together, not individual data points.
Does DataPoint.get_centroid() modify the cluster it is given?
No. It reads the items already in the supplied Cluster and returns a new
DataPoint for the centroid; the source cluster and its items are left
unchanged.
Is this clustering functionality specific to PDF content?
No. DataPoint, Cluster, and ClusterCollection are generic
numeric-clustering primitives shipped inside the aspose_pdf package. They
do not read pages, text, or any other PDF structure themselves — they operate
purely on the values you construct them with.
Why does Cluster.empty() return the same instance every time?
Cluster.empty() returns a shared singleton so that repeated calls for “no
cluster” do not allocate a new object on every call.
API Reference Summary
| Class/Method | Description |
|---|---|
DataPoint | A named point holding a list of numeric coordinates |
DataPoint.name | The point’s identifying name |
DataPoint.value | The point’s list of numeric coordinates |
DataPoint.get_centroid() | Returns a new DataPoint averaging every point’s coordinates in a cluster |
Cluster | A group of items, typically DataPoint instances |
Cluster.empty() | Returns the shared empty-cluster singleton |
Cluster.contains() | Checks whether an item is in the cluster |
Cluster.clone() | Returns an independent copy of the cluster |
Cluster.count | The number of items currently in the cluster |
ClusterCollection | Wraps a list of Cluster instances into one collection |