join#
- metatensor.join(tensors: List[TensorMap], axis: str, different_keys: str = 'error', remove_tensor_name: bool = False) TensorMap[source]#
Join a sequence of
TensorMapwith the same blocks along an axis.The
axisparameter 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
tensordimension from labels if possible. See examples above for the case where this is applicable.
- Return tensor_joined:
The stacked
TensorMapwith more properties or samples than the input TensorMap.- Return type:
Examples#
Possible clashes of the meta data like
samples/propertieswill be resolved by one of the three following strategies:If Labels names are the same, the values are unique and
remove_tensor_name=Truewe 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=FalseThere will be an extra dimensiontensoradded>>> 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_3has the same name and also shares values withproperties_1as 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_4has the different names compared toproperties_1defined 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 )