TensorMap#
- class metatensor.TensorMap(keys: Labels, blocks: Sequence[TensorBlock])[source]#
A TensorMap is the main user-facing class of this library, and can store any kind of data used in atomistic machine learning similar to a Python
dict
.A tensor map contains a list of
TensorBlock
, each one associated with a key. Blocks can either be accessed one by one with theTensorMap.block()
function, or by iterating over the tensor map itself:for block in tensor: ...
The corresponding keys can be included in the loop by using the
items()
method of aTensorMap()
:for key, block in tensor.items(): ...
A tensor map provides functions to move some of these keys to the samples or properties labels of the blocks, moving from a sparse representation of the data to a dense one.
- Parameters:
keys (Labels) – keys associated with each block
blocks (Sequence[TensorBlock]) – set of blocks containing the actual data
- copy() TensorMap [source]#
Get a deep copy of this TensorMap, including all the data and metadata
- Return type:
- static load(file: str | Path | BinaryIO, use_numpy=False) TensorMap [source]#
Load a serialized
TensorMap
from a file or a buffer, callingmetatensor.load()
.- Parameters:
file (str | Path | BinaryIO) – file path or file object to load from
use_numpy – should we use the numpy loader or metatensor’s. See
metatensor.load()
for more information.
- Return type:
- static load_buffer(buffer: bytes | bytearray | memoryview, use_numpy=False) Labels [source]#
Load a serialized
TensorMap
from a buffer, callingmetatensor.io.load_buffer()
.- Parameters:
buffer (bytes | bytearray | memoryview) – in-memory buffer containing the data
use_numpy – should we use the numpy loader or metatensor’s. See
metatensor.load()
for more information.
- Return type:
- save(file: str | Path | BinaryIO, use_numpy=False)[source]#
Save this
TensorMap
to a file or a buffer, callingmetatensor.save()
.- Parameters:
file (str | Path | BinaryIO) – file path or file object to save to
use_numpy – should we use the numpy serializer or metatensor’s. See
metatensor.save()
for more information.
- save_buffer(use_numpy=False) memoryview [source]#
Save this
TensorMap
to an in-memory buffer, callingmetatensor.io.save_buffer()
.- Parameters:
use_numpy – should we use numpy serialization or metatensor’s. See
metatensor.save()
for more information.- Return type:
- block_by_id(index: int) TensorBlock [source]#
Get the block at
index
in thisTensorMap
.- Parameters:
index (int) – index of the block to retrieve
- Return type:
- blocks_by_id(indices: Sequence[int]) TensorBlock [source]#
Get the blocks with the given
indices
in thisTensorMap
.- Parameters:
- Return type:
- blocks_matching(selection: Labels) List[int] [source]#
Get a (possibly empty) list of block indexes matching the
selection
.This function finds all keys in this
TensorMap
with the same values asselection
for the dimensions/names contained in theselection
; and return the corresponding indexes.The
selection
should contain a single entry.
- block(selection: None | int | Labels | LabelsEntry | Dict[str, int] = None, **kwargs) TensorBlock [source]#
Get the single block in this
TensorMap
matching theselection
.When
selection
is anint
, this is equivalent toTensorMap.block_by_id()
.When
selection
is anLabels
, it should only contain a single entry, which will be used for the selection.When
selection
is aDict[str, int]
, it is converted into a single singleLabelsEntry
(the dict keys becoming the names and the dict values being joined together to form theLabelsEntry
values), which is then used for the selection.When
selection
is aLabelsEntry
, this function finds the key in thisTensorMap
with the same values asselection
for the dimensions/names contained in theselection
; and return the corresponding indexes.If
selection
isNone
, the selection can be passed as keyword arguments, which will be converted to aDict[str, int]
.- Parameters:
selection (None | int | Labels | LabelsEntry | Dict[str, int]) – description of the block to extract
- Return type:
>>> from metatensor import TensorMap, TensorBlock, Labels >>> keys = Labels(["key_1", "key_2"], np.array([[0, 0], [6, 8]])) >>> block_1 = TensorBlock( ... values=np.full((3, 5), 1.0), ... samples=Labels.range("sample", 3), ... components=[], ... properties=Labels.range("property", 5), ... ) >>> block_2 = TensorBlock( ... values=np.full((5, 3), 2.0), ... samples=Labels.range("sample", 5), ... components=[], ... properties=Labels.range("property", 3), ... ) >>> tensor = TensorMap(keys, [block_1, block_2]) >>> # numeric index selection, this gives a block by its position >>> block = tensor.block(0) >>> block TensorBlock samples (3): ['sample'] components (): [] properties (5): ['property'] gradients: None >>> # This is the first block >>> block.values.mean() 1.0 >>> # use a single key entry (i.e. LabelsEntry) for the selection >>> tensor.block(tensor.keys[0]).values.mean() 1.0 >>> # Labels with a single entry selection >>> labels = Labels(names=["key_1", "key_2"], values=np.array([[6, 8]])) >>> tensor.block(labels).values.mean() 2.0 >>> # keyword arguments selection >>> tensor.block(key_1=0, key_2=0).values.mean() 1.0 >>> # dictionary selection >>> tensor.block({"key_1": 6, "key_2": 8}).values.mean() 2.0
- blocks(selection: None | Sequence[int] | int | Labels | LabelsEntry | Dict[str, int] = None, **kwargs) List[TensorBlock] [source]#
Get the blocks in this
TensorMap
matching theselection
.When
selection
isNone
(the default), all blocks are returned.When
selection
is anint
, this is equivalent toTensorMap.block_by_id()
; and for aList[int]
this is equivalent toTensorMap.blocks_by_id()
.When
selection
is anLabels
, it should only contain a single entry, which will be used for the selection.When
selection
is aDict[str, int]
, it is converted into a single singleLabelsEntry
(the dict keys becoming the names and the dict values being joined together to form theLabelsEntry
values), which is then used for the selection.When
selection
is aLabelsEntry
, this function finds all keys in thisTensorMap
with the same values asselection
for the dimensions/names contained in theselection
; and return the corresponding blocks.If
selection
isNone
, the selection can be passed as keyword arguments, which will be converted to aDict[str, int]
.
- keys_to_samples(keys_to_move: str | Sequence[str], *, sort_samples=True) TensorMap [source]#
Merge blocks along the samples axis, adding
keys_to_move
to the end of the samples labels dimensions.This function will remove
keys_to_move
from the keys, and find all blocks with the same remaining keys values. It will then merge these blocks along the samples direction (i.e. do a vertical concatenation), addingkeys_to_move
to the end of the samples labels dimensions. The values taken bykeys_to_move
in the new samples labels will be the values of these dimensions in the merged blocks’ keys.If
keys_to_move
is a set ofLabels
, it must be empty (keys_to_move.values.shape[0] == 0
), and only theLabels.names
will be used.The order of the samples is controlled by
sort_samples
. Ifsort_samples
is true, samples are re-ordered to keep them lexicographically sorted. Otherwise they are kept in the order in which they appear in the blocks.This function is only implemented when the blocks to merge have the same properties values.
- components_to_properties(dimensions: str | Sequence[str]) TensorMap [source]#
Move the given
dimensions
from the component labels to the property labels for each block.
- keys_to_properties(keys_to_move: str | Sequence[str] | Labels, *, sort_samples=True) TensorMap [source]#
Merge blocks along the properties direction, adding
keys_to_move
at the beginning of the properties labels dimensions.This function will remove
keys_to_move
from the keys, and find all blocks with the same remaining keys values. Then it will merge these blocks along the properties direction (i.e. do a horizontal concatenation).If
keys_to_move
is given as strings, then the new property labels will only contain entries from the existing blocks. For example, merging a block with keya=0
and propertiesp=1, 2
with a block with keya=2
and propertiesp=1, 3
will produce a block with propertiesa, p = (0, 1), (0, 2), (2, 1), (2, 3)
.If
keys_to_move
is a set ofLabels
and it is empty (len(keys_to_move) == 0
), theLabels.names
will be used as if they where passed directly.Finally, if
keys_to_move
is a non empty set ofLabels
, the new properties labels will contains all of the entries ofkeys_to_move
(regardless of the values taken bykeys_to_move.names
in the merged blocks’ keys) followed by the existing properties labels. For example, usinga=2, 3
inkeys_to_move
, blocks with propertiesp=1, 2
will result ina, p = (2, 1), (2, 2), (3, 1), (3, 2)
. If there is no values (no block/missing sample) for a given property in the merged block, then the value will be set to zero.When using a non empty
Labels
forkeys_to_move
, the properties labels of all the merged blocks must take the same values.The order of the samples in the merged blocks is controlled by
sort_samples
. Ifsort_samples
isTrue
, samples are re-ordered to keep them lexicographically sorted. Otherwise they are kept in the order in which they appear in the blocks.
- property component_names: List[str]#
names of the components dimensions for all blocks in this
TensorMap
- property property_names: List[str]#
names of the properties dimensions for all blocks in this
TensorMap
- print(max_keys: int) str [source]#
Print this
TensorMap
to a string, including at mostmax_keys
in the output.
- to(*, dtype: dtype | dtype | None = None, device: device | str | None = None, arrays: str | None = None) TensorMap [source]#
Move all the arrays in this block (values and gradients) to the given
dtype
,device
andarrays
backend.- Parameters:
dtype (dtype | dtype | None) – new dtype to use for all arrays. The dtype stays the same if this is set to
None
.device (device | str | None) – new device to use for all arrays. The device stays the same if this is set to
None
.arrays (str | None) – new backend to use for the arrays. This can be either
"numpy"
,"torch"
orNone
(keeps the existing backend)
- Return type: