
    ti#                        d dl Z d dlmZ d dlmZmZmZ d dlmZm	Z	 d dl
Z
d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d
dgZ e	dd      Z ed       G d dee                Zd Z ed       G d d
e             Zy)    N)
namedtuple)CallableIteratorSized)AnyTypeVar)default_collate)functional_datapipe)dataframe_wrapper)IterDataPipe)_check_unpickable_fnvalidate_input_colCollatorIterDataPipeMapperIterDataPipe_T_coT)	covariantmapc                   p     e Zd ZU dZeed<   eed<   	 	 d
dededdf fdZd Zde	e
   fdZdefd	Z xZS )r   a  
    Applies a function over each item from the source DataPipe (functional name: ``map``).

    The function can be any regular Python function or partial object. Lambda
    function is not recommended as it is not supported by pickle.

    Args:
        datapipe: Source Iterable DataPipe
        fn: Function being applied over each item
        input_col: Index or indices of data which ``fn`` is applied, such as:

            - ``None`` as default to apply ``fn`` to the data directly.
            - Integer(s) is used for list/tuple.
            - Key(s) is used for dict.

        output_col: Index of data where result of ``fn`` is placed. ``output_col`` can be specified
            only when ``input_col`` is not ``None``

            - ``None`` as default to replace the index that ``input_col`` specified; For ``input_col`` with
              multiple indices, the left-most one is used, and other indices will be removed.
            - Integer is used for list/tuple. ``-1`` represents to append result at the end.
            - Key is used for dict. New key is acceptable.

    Example:
        >>> # xdoctest: +SKIP
        >>> from torchdata.datapipes.iter import IterableWrapper, Mapper
        >>> def add_one(x):
        ...     return x + 1
        >>> dp = IterableWrapper(range(10))
        >>> # Invocation via functional form is preferred
        ... map_dp_1 = dp.map(add_one)
        >>> list(map_dp_1)
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        >>> # We discourage the usage of `lambda` functions as they are not serializable with `pickle`
        >>> # Use `functools.partial` or explicitly define the function instead
        >>> map_dp_2 = Mapper(dp, lambda x: x + 1)
        >>> list(map_dp_2)
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    datapipefnNreturnc                 L   t         j                  j                  d       t        |           || _        t        |       || _        || _        ||t        d      t        |t        t        f      rt        |      dkD  rt        d      |d   }|| _        t        ||       y )Nzpython.data_pipes.mapz3`output_col` must be None when `input_col` is None.   z3`output_col` must be a single-element list or tupler   )torch_C_log_api_usage_oncesuper__init__r   r   r   	input_col
ValueError
isinstancelisttuplelen
output_colr   )selfr   r   r   r%   	__class__s        n/home/ubuntu/crypto_trading_bot/.venv/lib/python3.12/site-packages/torch/utils/data/datapipes/iter/callable.pyr   zMapperIterDataPipe.__init__H   s     	$$%<= R "!7RSSj4-0:" !VWW#AJ$2y)    c                 
   | j                   | j                  | j                        S | j                   | j                        }nlt        | j                   t        t
        f      r.t        fd| j                   D              } | j                  | }n| j                  | j                            }t        t
              rd}t	              nd}| j                  et        | j                   t        t
        f      r5|| j                   d   <   t        | j                   dd  d      D ]  }|=  n@|| j                   <   n0| j                  dk(  rj                  |       n|| j                  <   |rt              S S )Nc              3   (   K   | ]	  }|     y wN ).0coldatas     r(   	<genexpr>z/MapperIterDataPipe._apply_fn.<locals>.<genexpr>g   s     =sc=s   TFr   r   )reverse)r   r%   r   r!   r"   r#   sortedappend)r&   r0   resargst_flagidxs    `    r(   	_apply_fnzMapperIterDataPipe._apply_fn`   sF   >>!doo&=774= >>!''$-Cu6=dnn==D$''4.C''$t~~./C dE"F:DF??"$..4-8*-T^^A&'!$.."4dC "CS	" (+T^^$"$C (+T__% %uT{.$.r)   c              #   T   K   | j                   D ]  }| j                  |        y wr,   )r   r:   )r&   r0   s     r(   __iter__zMapperIterDataPipe.__iter__   s(     MM 	'D..&&	's   &(c                     t        | j                  t              rt        | j                        S t	        t        |       j                   d      )Nz# instance doesn't have valid length)r!   r   r   r$   	TypeErrortype__name__)r&   s    r(   __len__zMapperIterDataPipe.__len__   s=    dmmU+t}}%%4:..//RSTTr)   )NN)r@   
__module____qualname____doc__r   __annotations__r   r   r:   r   r   r<   intrA   __classcell__r'   s   @r(   r   r      sc    &P L ** * 
*0"/H'(5/ 'U Ur)   c                    t        |j                        dkD  rt        d      |d   }t        j                  |      }g }g }| D ]  }||vst        d       |D ]|  }|| v rt        | |         st        d      | |   }n!	 dd lm} |j                  j                         }|j                  t        |              |||         }
|j                  |
       ~ t        d|      } || }|S # t        $ r}	t        d      |	d }	~	ww xY w)Nr   z%Only supports one DataFrame per batchr   zConversion keys mismatchz5Collate (DF)DataPipe requires callable as dict valuesz?unable to import default collation function from the TorchArrowCollateResult)r$   itemsRuntimeError
df_wrapperget_columnscallabletorcharrow.pytorchpytorchrecDefault	Exceptionr5   strr   )
conversionitemdfcolumns_nametuple_namestuple_valuesnamecollation_fntapevaluetpl_clsr#   s                r(   _collate_helperrb      s0   
4::BCC	aB))"-LKL ;|#9::;  #:Jt,-"K  &d+L0"ww0 	3t9%RX&E")#0 +6G\"EL  "Us    C,,	D5DDcollatec            	       l     e Zd ZdZedfdededef   ee	ez  eez  f   z  dz  dedz  ddf fdZ
 xZS )	r   aI  
    Collates samples from DataPipe to Tensor(s) by a custom collate function (functional name: ``collate``).

    By default, it uses :func:`torch.utils.data.default_collate`.

    .. note::
        While writing a custom collate function, you can import :func:`torch.utils.data.default_collate` for the
        default behavior and `functools.partial` to specify any additional arguments.

    Args:
        datapipe: Iterable DataPipe being collated
        collate_fn: Customized collate function to collect and combine data or a batch of data.
            Default function collates to Tensor(s) based on data type.

    Example:
        >>> # xdoctest: +SKIP
        >>> # Convert integer data to float Tensor
        >>> class MyIterDataPipe(torch.utils.data.IterDataPipe):
        ...     def __init__(self, start, end):
        ...         super(MyIterDataPipe).__init__()
        ...         assert end > start, "this example only works with end >= start"
        ...         self.start = start
        ...         self.end = end
        ...
        ...     def __iter__(self):
        ...         return iter(range(self.start, self.end))
        ...
        ...     def __len__(self):
        ...         return self.end - self.start
        >>> ds = MyIterDataPipe(start=3, end=7)
        >>> print(list(ds))
        [3, 4, 5, 6]
        >>> def collate_fn(batch):
        ...     return torch.tensor(batch, dtype=torch.float)
        >>> collated_ds = CollateIterDataPipe(ds, collate_fn=collate_fn)
        >>> print(list(collated_ds))
        [tensor(3.), tensor(4.), tensor(5.), tensor(6.)]
    Nr   rV   .
collate_fnr   c                     |t         |   ||       y t        |      rt         |   ||       y t        j                  t
        |      }t         |   ||       y )N)r   )r   r   rO   	functoolspartialrb   )r&   r   rV   re   r'   s       r(   r   zCollatorIterDataPipe.__init__   s]     !GX*5
# j 9 '..
K
 j 9r)   )r@   rB   rC   rD   r	   r   r   r   dictrU   r   rG   rH   s   @r(   r   r      sp    %X !&*:: S#X&
sSy(S.(
)*
: tO: 
: :r)   )rg   collectionsr   collections.abcr   r   r   typingr   r   r   torch.utils.data._utils.collater	   %torch.utils.data.datapipes._decoratorr
   $torch.utils.data.datapipes.dataframer   rM   #torch.utils.data.datapipes.datapiper   'torch.utils.data.datapipes.utils.commonr   r   __all__r   r   rb   r   r-   r)   r(   <module>rs      s     " 5 5   ; E P <  	4( UoUe, oU oUd(V Y::- ::  ::r)   