join#
- metatensor.join(tensors: List[TensorMap], axis: str, different_keys: str = 'error', remove_tensor_name: bool = False) TensorMap [source]#
Join a sequence of
TensorMap
with the same blocks along an axis.The
axis
parameter specifies the type of joining. For example, ifaxis='properties'
the tensor maps in tensors will be joined along the properties dimension and foraxis='samples'
they will be the along the samples dimension.- Parameters:
axis (str) – A string indicating how the tensormaps are stacked. Allowed values are
'properties'
or'samples'
.different_keys (str) – Method to handle different keys between the tensors. For
"error"
keys in all tensors have to be the same. For"intersection"
only blocks present in all tensors will be taken into account. For"union"
missing keys will be treated like if they where associated with an empty block.remove_tensor_name (bool) – Remove the extra
tensor
dimension from labels if possible. See examples above for the case where this is applicable.
- Return tensor_joined:
The stacked
TensorMap
with more properties or samples than the input TensorMap.- Return type:
Examples#
Possible clashes of the meta data like
samples
/properties
will be resolved by one of the three following strategies:If Labels names are the same, the values are unique and
remove_tensor_name=True
we keep the names and join the values>>> import numpy as np >>> import metatensor >>> from metatensor import Labels, TensorBlock, TensorMap
>>> values = np.array([[1.1, 2.1, 3.1]]) >>> samples = Labels("sample", np.array([[0]]))
Define two disjoint
Labels
.>>> properties_1 = Labels("n", np.array([[0], [2], [3]])) >>> properties_2 = Labels("n", np.array([[1], [4], [5]]))
>>> block_1 = TensorBlock( ... values=values, ... samples=Labels.single(), ... components=[], ... properties=properties_1, ... ) >>> block_2 = TensorBlock( ... values=values, ... samples=Labels.single(), ... components=[], ... properties=properties_2, ... )
>>> tensor_1 = TensorMap(keys=Labels.single(), blocks=[block_1]) >>> tensor_2 = TensorMap(keys=Labels.single(), blocks=[block_2])
joining along the properties leads
>>> joined_tensor = metatensor.join( ... [tensor_1, tensor_2], axis="properties", remove_tensor_name=True ... ) >>> joined_tensor[0].properties Labels( n 0 2 3 1 4 5 )
If
remove_tensor_name=False
There will be an extra dimensiontensor
added>>> joined_tensor = metatensor.join( ... [tensor_1, tensor_2], axis="properties", remove_tensor_name=False ... ) >>> joined_tensor[0].properties Labels( tensor n 0 0 0 2 0 3 1 1 1 4 1 5 )
If Labels names are the same but the values are not unique, a new dimension
"tensor"
is added to the names.>>> properties_3 = Labels("n", np.array([[0], [2], [3]]))
properties_3
has the same name and also shares values withproperties_1
as defined above.>>> block_3 = TensorBlock( ... values=values, ... samples=Labels.single(), ... components=[], ... properties=properties_3, ... ) >>> tensor_3 = TensorMap(keys=Labels.single(), blocks=[block_3])
joining along properties leads to
>>> joined_tensor = metatensor.join([tensor_1, tensor_3], axis="properties") >>> joined_tensor[0].properties Labels( tensor n 0 0 0 2 0 3 1 0 1 2 1 3 )
If Labels names are different we change the names to (“tensor”, “property”). This case is only supposed to happen when joining in the property dimension, hence the choice of names:
>>> properties_4 = Labels(["a", "b"], np.array([[0, 0], [1, 2], [1, 3]]))
properties_4
has the different names compared toproperties_1
defined above.>>> block_4 = TensorBlock( ... values=values, ... samples=Labels.single(), ... components=[], ... properties=properties_4, ... ) >>> tensor_4 = TensorMap(keys=Labels.single(), blocks=[block_4])
joining along properties leads to
>>> joined_tensor = metatensor.join([tensor_1, tensor_4], axis="properties") >>> joined_tensor[0].properties Labels( tensor property 0 0 0 1 0 2 1 0 1 1 1 2 )