TensorDictBase.named_apply#
- TensorDictBase.named_apply(fn: Callable, *others: T, nested_keys: bool = False, batch_size: Sequence[int] | None = None, device: device | None = NO_DEFAULT, names: Sequence[str] | None = NO_DEFAULT, inplace: bool = False, default: Any = NO_DEFAULT, filter_empty: bool | None = None, propagate_lock: bool = False, call_on_nested: bool = False, is_leaf: Callable[[type], bool] | None = None, out: TensorDictBase | None = None, **constructor_kwargs) Self | None#
Applies a callable to every leaf and its key, and returns a new tensordict with the results.
Same as
apply(), except thatfnalso receives the key of each leaf: the last string of its nested key, or the whole nested key withnested_keys=True. IffnreturnsNone, the entry is left out of the result, which can be used to filter entries by key.- Parameters:
fn (Callable) – the function called on each leaf, as
fn(key, leaf, *other_leaves). It returns a tensor, a tensordict, orNoneto leave the entry out.*others (TensorDictBase) – other tensordicts with the same structure as the tensordict. An entry that one of them lacks raises
KeyError, unlessdefaultis given.
- Keyword Arguments:
nested_keys (bool, optional) – if
True,fnreceives the whole nested key of each leaf, a tuple of strings for an entry of a nested tensordict. IfFalse, it receives the last string of the key. Defaults toFalse.batch_size (Size or list of int, optional) – the batch size of the result, for a
fnthat changes the shape of the leaves: the results must have it as their leading dimensions.fnis then not called onUnbatchedTensorentries, which keep their data and take the new batch size. Defaults toNone, which keeps the batch size of the tensordict.device (device, str or int, optional) – the device of the result. The results of
fnare moved to it.Nonegives a result with no device, which leaves each result wherefnput it. By default, the result has the device of the tensordict.names (list of str, optional) – the names of the batch dimensions of the result, one per dimension. By default, the names of the tensordict are kept, or dropped if
batch_sizeis given.inplace (bool, optional) – if
True, the results are written into the existing leaves of the tensordict (asset_()does), andselfis returned. See In-place operations. Defaults toFalse.default (Any, optional) – the value passed to
fnfor an entry that one ofotherslacks. By default, a missing entry raisesKeyError.filter_empty (bool, optional) – if
True, a nested tensordict with no entry in the result (becausefnreturnedNonefor all its leaves, or because it was already empty) is left out. IfFalse, it is kept, empty. Defaults toNone, which leaves out the nested tensordicts thatfnemptied and keeps those that were already empty. Non-tensor data thatfnis not called on is kept in all cases.propagate_lock (bool, optional) – if
True, the result of a locked tensordict is locked too. Defaults toFalse.call_on_nested (bool, optional) – if
True,fnis called on the top-level entries, nested tensordicts and tensorclasses included, and is responsible for going into them. IfFalse,fnis called on the leaves only. Defaults toFalse.is_leaf (Callable, optional) – called with the type of each entry:
fnis called on the entries for which it returnsTrue, andnamed_applygoes into the others. Defaults toNone, which usesdefault_is_leaf():fnis called on tensors, and non-tensor data is kept unchanged. Passis_leaf_nontensor()to callfnon non-tensor data too.out (TensorDictBase, optional) – a tensordict to write the results into, instead of a new one. When
batch_sizeordeviceis given,outmust have it. For a lazy stack,outmust be a lazy stack too, stacked along any dimension. See the warning below aboutout=self. Defaults toNone.**constructor_kwargs – ignored, with a
FutureWarning. Starting with TensorDict 0.17, the default will change to raising aTypeErrorfor them.
- Returns:
A new tensordict,
outif it is given, orselfifinplace=True.NoneiffnreturnsNonefor every leaf andfilter_emptyis notFalse. Withfilter_empty=None, a tensordict that is already empty gives an empty tensordict.The result has the type of the tensordict for a
TensorDict, a lazy stack and a tensorclass. Other types, for examplePersistentTensorDictor a memory-mapped tensordict, give aTensorDictthat lives in memory. A locked tensordict gives an unlocked result unlesspropagate_lock=True.
Warning
With
out=self, the results are silently wrong iffnreads other entries of the tensordict, which may already be overwritten.Examples
>>> import torch >>> from tensordict import TensorDict >>> td = TensorDict( ... a=torch.zeros(3), ... nested=TensorDict(a=torch.ones(3), b=torch.ones(3), batch_size=[3]), ... batch_size=[3], ... ) >>> out = td.named_apply(lambda key, x: x if key == "a" else None) >>> list(out.keys(include_nested=True, leaves_only=True)) ['a', ('nested', 'a')] >>> out = td.named_apply( ... lambda key, x: x + 1 if key == ("nested", "b") else x, ... nested_keys=True, ... ) >>> out["nested", "b"], out["nested", "a"] (tensor([2., 2., 2.]), tensor([1., 1., 1.]))
With another tensordict,
fnreceives one leaf of each:>>> td.named_apply(lambda key, x, y: x + y, td)["nested", "a"] tensor([2., 2., 2.])
Every tensordict class and every tensorclass has this method. For the other methods, see Methods by task.