class_docstr: Wrap multiple batchify functions together and apply it to merge inputs from a namedtuple.
  
  The generated batch samples are stored as a namedtuple with the same structure.
  
  Each data sample should be a namedtuple. The `i`th batchify
  function stored in `NamedTuple` will be applied on the `i`th attribute of the namedtuple data.
  For example, each data sample is Sample(data=nd_data, label=nd_label).
  You can wrap two batchify functions using
  `NamedTuple(Sample, {'data': DataBatchify, 'label': LabelBatchify})` to
  batchify nd_data and nd_label correspondingly. The result will be stored as a Sample object
  and you can access the data and label via `sample.data` and `sample.label`, correspondingly.
  
  Parameters
  ----------
  container
      The object that constructs the namedtuple.
  fn_info
      The information of the inner batchify functions.
  
  Examples
  --------
  >>> from gluonnlp.data.batchify import NamedTuple, Pad, Stack
  >>> from collections import namedtuple
  >>> SampleData = namedtuple('SampleData', ['data', 'label'])
  >>> a = SampleData([1, 2, 3, 4], 0)
  >>> b = SampleData([5, 7], 1)
  >>> c = SampleData([1, 2, 3, 4, 5, 6, 7], 0)
  >>> batchify_fn = NamedTuple(SampleData, {'data': Pad(), 'label': Stack()})
  >>> sample = batchify_fn([a, b, c])
  >>> sample
  SampleData(data=
  [[1. 2. 3. 4. 0. 0. 0.]
   [5. 7. 0. 0. 0. 0. 0.]
   [1. 2. 3. 4. 5. 6. 7.]]
  <NDArray 3x7 @cpu_shared(0)>, label=
  [0 1 0]
  <NDArray 3 @cpu_shared(0)>)
  >>> sample.data
  <BLANKLINE>
  [[1. 2. 3. 4. 0. 0. 0.]
   [5. 7. 0. 0. 0. 0. 0.]
   [1. 2. 3. 4. 5. 6. 7.]]
  <NDArray 3x7 @cpu_shared(0)>
  >>> # Let's consider to use a list
  >>> batchify_fn = NamedTuple(SampleData, [Pad(), Stack()])
  >>> batchify_fn([a, b, c])
  SampleData(data=
  [[1. 2. 3. 4. 0. 0. 0.]
   [5. 7. 0. 0. 0. 0. 0.]
   [1. 2. 3. 4. 5. 6. 7.]]
  <NDArray 3x7 @cpu_shared(0)>, label=
  [0 1 0]
  <NDArray 3 @cpu_shared(0)>)
docstr: Batchify the input data.
  
  Parameters
  ----------
  data
      The samples to batchfy. Each sample should be a namedtuple.
  
  Returns
  -------
  ret
      A namedtuple of length N. Contains the batchified result of each attribute in the input.
docstr_tok: ["Batchify","the","input","data",".","Parameters","--","--","--","--","--","data","The","samples","to","batchfy",".","Each","sample","should","be","a","namedtuple",".","Returns","--","--","--","-","ret","A","namedtuple","of","length","N.","Contains","the","batchified","result","of","each","attribute","in","the","input","."]
code: def __call__(self, data: t_List[t_NamedTuple]) -> t_NamedTuple:
      """Batchify the input data.
  
      Parameters
      ----------
      data
          The samples to batchfy. Each sample should be a namedtuple.
  
      Returns
      -------
      ret
          A namedtuple of length N. Contains the batchified result of each attribute in the input.
      """
      if not isinstance(data[0], self._container):
          raise ValueError(
              "The samples should have the same type as the stored namedtuple."
              " data[0]={}, container={}".format(
                  data[0], self._container
              )
          )
      ret = []
      for i, ele_fn in enumerate(self._fn_l):
          ret.append(ele_fn([ele[i] for ele in data]))
      return self._container(*ret)
  
imports: import warnings
  import math
  from typing import Dict, Callable, NamedTuple, List, Tuple, AnyStr, Union
  import numpy
  import mxnet
  from mxnet.util import is_np_array
label_desc: Use image node_id 2 for calling the NamedTuple obj's underlying member method code with example usage: obj.__call__(data) and returns: self