Labels¶
- class metatensor.Labels(names: str | Sequence[str], values: ndarray)[source]¶
A set of labels carrying metadata associated with a
TensorMap
.The metadata can be though as a list of tuples, where each value in the tuple also has an associated dimension name. In practice, the dimensions
names
are stored separately from thevalues
, and the values are in a 2-dimensional array integers with the shape(n_entries, n_dimensions)
. Each row/entry in this array is unique, and they are often (but not always) sorted in lexicographic order.>>> from metatensor import Labels >>> import numpy as np >>> labels = Labels( ... names=["system", "atom", "center_type"], ... values=np.array([(0, 1, 8), (0, 2, 1), (0, 5, 1)]), ... ) >>> labels Labels( system atom center_type 0 1 8 0 2 1 0 5 1 ) >>> labels.names ['system', 'atom', 'center_type'] >>> print(labels.values) [[0 1 8] [0 2 1] [0 5 1]]
It is possible to create a view inside a
Labels
, selecting a subset of columns/dimensions:>>> # single dimension >>> view = labels.view("atom") >>> view.names ['atom'] >>> print(view.values) [[1] [2] [5]] >>> # multiple dimensions >>> view = labels.view(["atom", "system"]) >>> view.names ['atom', 'system'] >>> print(view.values) [[1 0] [2 0] [5 0]] >>> view.is_view() True >>> # we can convert a view back to a full, owned Labels >>> owned_labels = view.to_owned() >>> owned_labels.is_view() False
One can also iterate over labels entries, or directly index the
Labels
to get a specific entry>>> entry = labels[0] # or labels.entry(0) >>> entry.names ['system', 'atom', 'center_type'] >>> print(entry.values) [0 1 8] >>> for entry in labels: ... print(entry) ... LabelsEntry(system=0, atom=1, center_type=8) LabelsEntry(system=0, atom=2, center_type=1) LabelsEntry(system=0, atom=5, center_type=1)
Or get all the values associated with a given dimension/column name
>>> print(labels.column("atom")) [1 2 5] >>> print(labels["atom"]) # alternative syntax for the above [1 2 5]
Labels can be checked for equality:
>>> owned_labels == labels False >>> labels == labels True
Finally, it is possible to check if a value is inside (non-view) labels, and get the corresponding position:
>>> labels.position([0, 2, 1]) 1 >>> print(labels.position([0, 2, 4])) None >>> (0, 2, 4) in labels False >>> labels[2] in labels True
- Parameters:
- static single() Labels [source]¶
Create
Labels
to use when there is no relevant metadata and only one entry in the corresponding dimension (e.g. keys when a tensor map contains a single block).- Return type:
- static empty(names: str | Sequence[str]) Labels [source]¶
Create
Labels
with givennames
but no values.
- static range(name: str, end: int) Labels [source]¶
Create
Labels
with a single dimension using the givenname
and values in the[0, end)
range.- Parameters:
- Return type:
>>> from metatensor import Labels >>> labels = Labels.range("dummy", 7) >>> labels.names ['dummy'] >>> print(labels.values) [[0] [1] [2] [3] [4] [5] [6]]
- static load(file: str | Path | BinaryIO) Labels [source]¶
Load a serialized
Labels
from a file, callingmetatensor.load_labels()
.
- static load_buffer(buffer: bytes | bytearray | memoryview) Labels [source]¶
Load a serialized
Labels
from a buffer, callingmetatensor.io.load_labels_buffer()
.- Parameters:
buffer (bytes | bytearray | memoryview) – in-memory buffer containing the data
- Return type:
- save_buffer() memoryview [source]¶
Save these
Labels
to an in-memory buffer, callingmetatensor.io.save_buffer()
.- Return type:
- property values: ndarray¶
values associated with each dimensions of the
Labels
, stored as 2-dimensional tensor of 32-bit integers
- append(name: str, values: ndarray) Labels [source]¶
Append a new dimension to the end of the
Labels
.- Parameters:
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> label = Labels("foo", np.array([[42]])) >>> label Labels( foo 42 ) >>> label.append(name="bar", values=np.array([10])) Labels( foo bar 42 10 )
- insert(index: int, name: str, values: ndarray) Labels [source]¶
Insert a new dimension before
index
in theLabels
.- Parameters:
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> label = Labels("foo", np.array([[42]])) >>> label Labels( foo 42 ) >>> label.insert(0, name="bar", values=np.array([10])) Labels( bar foo 10 42 )
- permute(dimensions_indexes: List[int]) Labels [source]¶
Permute dimensions according to
dimensions_indexes
in theLabels
.- Parameters:
dimensions_indexes (List[int]) – desired ordering of the dimensions
- Raises:
ValueError – if length of
dimensions_indexes
does not match the Labels lengthValueError – if duplicate values are present in
dimensions_indexes
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> label = Labels(["foo", "bar", "baz"], np.array([[42, 10, 3]])) >>> label Labels( foo bar baz 42 10 3 ) >>> label.permute([2, 0, 1]) Labels( baz foo bar 3 42 10 )
- remove(name: str) Labels [source]¶
Remove
name
from the dimensions of theLabels
.Removal can only be performed if the resulting
Labels
instance will be unique.- Parameters:
name (str) – name to be removed
- Raises:
ValueError – if the name is not present.
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> label = Labels(["foo", "bar"], np.array([[42, 10]])) >>> label Labels( foo bar 42 10 ) >>> label.remove(name="bar") Labels( foo 42 )
If the new
Labels
is not unique an error is raised.>>> from metatensor import MetatensorError >>> label = Labels(["foo", "bar"], np.array([[42, 10], [42, 11]])) >>> label Labels( foo bar 42 10 42 11 ) >>> try: ... label.remove(name="bar") ... except MetatensorError as e: ... print(e) ... invalid parameter: can not have the same label value multiple time: [42] is already present at position 0
- rename(old: str, new: str) Labels [source]¶
Rename the
old
dimension tonew
in theLabels
.- Parameters:
- Raises:
ValueError – if old is not present.
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> label = Labels("foo", np.array([[42]])) >>> label Labels( foo 42 ) >>> label.rename("foo", "bar") Labels( bar 42 )
- to(device) Labels [source]¶
Move the values for these Labels to the given
device
.In the Python version of metatensor, this returns the original labels. Defined for compatibility with the TorchScript version of metatensor.
- Return type:
- property device: str¶
Get the device of these Labels.
This exists for compatibility with the TorchScript API, and always returns
"cpu"
when called.
- position(entry: LabelsEntry | Sequence[int]) int | None [source]¶
Get the position of the given
entry
in this set ofLabels
, orNone
if the entry is not present in the labels.- Parameters:
entry (LabelsEntry | Sequence[int])
- Return type:
int | None
- union(other: Labels) Labels [source]¶
Take the union of these
Labels
withother
.If you want to know where entries in
self
andother
ends up in the union, you can useLabels.union_and_mapping()
.>>> import numpy as np >>> from metatensor import Labels >>> first = Labels(names=["a", "b"], values=np.array([[0, 1], [1, 2], [0, 3]])) >>> second = Labels(names=["a", "b"], values=np.array([[0, 3], [1, 3], [1, 2]])) >>> first.union(second) Labels( a b 0 1 1 2 0 3 1 3 )
- union_and_mapping(other: Labels) Tuple[Labels, ndarray, ndarray] [source]¶
Take the union of these
Labels
withother
.This function also returns the position in the union where each entry of the input :py:class::Labels ended up.
- Returns:
Tuple containing the union, a
numpy.ndarray
containing the position in the union of the entries fromself
, and anumpy.ndarray
containing the position in the union of the entries fromother
.- Parameters:
other (Labels)
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> first = Labels(names=["a", "b"], values=np.array([[0, 1], [1, 2], [0, 3]])) >>> second = Labels(names=["a", "b"], values=np.array([[0, 3], [1, 3], [1, 2]])) >>> union, mapping_1, mapping_2 = first.union_and_mapping(second) >>> union Labels( a b 0 1 1 2 0 3 1 3 ) >>> print(mapping_1) [0 1 2] >>> print(mapping_2) [2 3 1]
- intersection(other: Labels) Labels [source]¶
Take the intersection of these
Labels
withother
.If you want to know where entries in
self
andother
ends up in the intersection, you can useLabels.intersection_and_mapping()
.>>> import numpy as np >>> from metatensor import Labels >>> first = Labels(names=["a", "b"], values=np.array([[0, 1], [1, 2], [0, 3]])) >>> second = Labels(names=["a", "b"], values=np.array([[0, 3], [1, 3], [1, 2]])) >>> first.intersection(second) Labels( a b 1 2 0 3 )
- intersection_and_mapping(other: Labels) Tuple[Labels, ndarray, ndarray] [source]¶
Take the intersection of these
Labels
withother
.This function also returns the position in the intersection where each entry of the input
Labels
ended up.- Returns:
Tuple containing the intersection, a
numpy.ndarray
containing the position in the intersection of the entries fromself
, and anumpy.ndarray
containing the position in the intersection of the entries fromother
. If entries inself
orother
are not used in the output, the mapping for them is set to-1
.- Parameters:
other (Labels)
- Return type:
>>> import numpy as np >>> from metatensor import Labels >>> first = Labels(names=["a", "b"], values=np.array([[0, 1], [1, 2], [0, 3]])) >>> second = Labels(names=["a", "b"], values=np.array([[0, 3], [1, 3], [1, 2]])) >>> intersection, mapping_1, mapping_2 = first.intersection_and_mapping(second) >>> intersection Labels( a b 1 2 0 3 ) >>> print(mapping_1) [-1 0 1] >>> print(mapping_2) [ 1 -1 0]
- select(selection: Labels) ndarray [source]¶
Select entries in these
Labels
that match theselection
.The selection’s names must be a subset of the names of these labels.
All entries in these
Labels
that match one of the entry in theselection
for all the selection’s dimension will be picked. Any entry in theselection
but not in theseLabels
will be ignored.>>> import numpy as np >>> from metatensor import Labels >>> labels = Labels( ... names=["a", "b"], ... values=np.array([[0, 1], [1, 2], [0, 3], [1, 1], [2, 4]]), ... ) >>> selection = Labels(names=["a"], values=np.array([[0], [2], [5]])) >>> print(labels.select(selection)) [0 2 4]
- entry(index: int) LabelsEntry [source]¶
Get a single entry/row in these labels.
See also
Labels.__getitem__()
as the main way to use this function- Parameters:
index (int)
- Return type:
- column(dimension: str) ndarray [source]¶
Get the values associated with a single dimension in these labels (i.e. a single column of
Labels.values
) as a 1-dimensional array.See also
Labels.__getitem__()
as the main way to use this functionLabels.view()
to access multiple columns simultaneously
- view(dimensions: str | Sequence[str]) Labels [source]¶
Get a view for the specified columns in these labels.
See also
Labels.column()
to get the values associated with a single dimension
- is_view() bool [source]¶
are these labels a view inside another set of labels?
A view is created with
Labels.__getitem__()
orLabels.view()
, and does not implementLabels.position()
orLabels.__contains__()
.- Return type:
- class metatensor.labels.LabelsEntry(names: List[str], values: LabelsValues)[source]¶
A single entry (i.e. row) in a set of
Labels
.The main way to create a
LabelsEntry
is to index aLabels
or iterate over them.>>> from metatensor import Labels >>> import numpy as np >>> labels = Labels( ... names=["system", "atom", "center_type"], ... values=np.array([(0, 1, 8), (0, 2, 1), (0, 5, 1)]), ... ) >>> entry = labels[0] # or labels.entry(0) >>> entry.names ['system', 'atom', 'center_type'] >>> print(entry.values) [0 1 8]
- Parameters:
values (LabelsValues)
- property values: LabelsValues¶
values associated with each dimensions of this Labels entry, stored as 32-bit integers.