
    }ig                       U d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	m
Z
mZ d dlZd dlZd dlmZ d dlmZmZmZmZmZmZ d dlmZ d dlmZmZmZmZm Z m!Z!m"Z" d dl#m$Z$ erd d	l%m&Z&m'Z'm(Z( d d
l)m*Z* d dl+Z,d dl-m.Z/ d dl0m1Z1 d dl2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z: d dl;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZBmCZCmDZDmEZE  e
de8          ZFeDZGdeHd<   eDZIdeHd<   eeeJgef         ZKdeHd<   eJZLdeHd<   ejM        ejN        ejO        hZPdZQ ejR        eQejS                  ZTdZU ejR        eUejS                  ZVe	d         ZWdeHd<   dd d!ZXd"d#d$d%d&d'd(d)d*d+d,
ZYd-eHd.<   ejM        Z                                Z[	  e!e          Z\	 dd3Z]dd9Z^dd>Z_ddAZ` eja        dBC          ddE            Zb eja        dBC          ddI            ZcddLZdddNZeddPZfdQZgdRdSddUZhejM        Z                                dVk    rddYZinddZZidd\Zjdd`Zk eja        dBC          ddb            Zlejm        jn        Znenjo        dcenjp        ddiZqdeeHdf<   enjr        dgdhdidjenjs        dkdldmdjenjt        dndodpdjenju        dqdrdsdjenjv        dtdudvdjenjw        dwdxdydjenjx        dzd{d|djenjy        d}d~ddjenjz        ddddjenj{        ddddjenj|        ddd2djiZ}deHd<   ddZ~ddZddZej        dfej        dfej        efej        dfej        efej        dfej        efej        efej        efd	ZdeHd<   ddZeeeddZdeHd<   ddZddZddZddZ G d ded5ef                   ZddZddZdS )    )annotationsN)TYPE_CHECKINGAnyCallableLiteralTypeVarcast)EagerSeriesNamespace)MS_PER_SECONDNS_PER_MICROSECONDNS_PER_MILLISECONDNS_PER_SECONDSECONDS_PER_DAYUS_PER_SECOND)issue_warning)ImplementationVersion_DeferredIterablecheck_columns_existisinstance_or_issubclassparse_versionrequires)
ShapeError)IterableIteratorMapping)
ModuleType)DtypeBaseMaskedDtype)	TypeAliasTypeIs)IntervalUnit)PandasLikeExprPandasLikeSeries)NativeDataFrameTNativeNDFrameTNativeSeriesT)DType)DTypeBackend	IntoDTypeTimeUnit_1DArrayExprT)boundr!   UnitCurrent
UnitTargetBinOpBroadcastIntoRhsa  ^
    datetime64\[
        (?P<time_unit>s|ms|us|ns)                 # Match time unit: s, ms, us, or ns
        (?:,                                      # Begin non-capturing group for optional timezone
            \s*                                   # Optional whitespace after comma
            (?P<time_zone>                        # Start named group for timezone
                [a-zA-Z\/]+                       # Match timezone name, e.g., UTC, America/New_York
                (?:[+-]\d{2}:\d{2})?              # Optional offset in format +HH:MM or -HH:MM
                |                                 # OR
                pytz\.FixedOffset\(\d+\)          # Match pytz.FixedOffset with integer offset in parentheses
            )                                     # End time_zone group
        )?                                        # End optional timezone group
    \]                                            # Closing bracket for datetime64
$z^
    timedelta64\[
        (?P<time_unit>s|ms|us|ns)                 # Match time unit: s, ms, us, or ns
    \]                                            # Closing bracket for timedelta64
$)yearquartermonthweekdayhourminutesecondmillisecondmicrosecond
nanosecondNativeIntervalUnitDmin)dmr5   r6   r7   r9   r:   r;   r<   r=   r>   r?   )
yqmorC   hrD   smsusnsz)Mapping[IntervalUnit, NativeIntervalUnit]
UNITS_DICTimplementationr   returnboolc                6    | t           j        t           j        hv S N)r   PANDASMODINrN   s    O/home/jrussi/.local/lib/python3.11/site-packages/narwhals/_pandas_like/utils.pyis_pandas_or_modinrW      s    n3^5IJJJ    lhsr&   rhsPandasLikeSeries | object.tuple[pd.Series[Any], pd.Series[Any] | object]c                   ddl m} | j        j        }| j        r0t          ||          r |j        s| j        j        d         |j        fS t          ||          r_|j        r| j        |j        j        d         fS |j        j        |ur#| j        t          |j        ||j                  fS | j        |j        fS t          |t                    rd}t          |          | j        |fS )zValidate RHS of binary operation.

    If the comparison isn't supported, return `NotImplemented` so that the
    "right-hand-side" operation (e.g. `__radd__`) can be tried.
    r   r%   rU   z$Expected Series or scalar, got list.)narwhals._pandas_like.seriesr&   nativeindex
_broadcast
isinstanceiloc	set_index_implementationlist	TypeError)rY   rZ   r&   	lhs_indexmsgs        rV   align_and_extract_nativerj      s    >=====
 I
~ .*S*:;; .CN .zq!3:--#'(( (> 	4J
 233:9,,
#*i@STTT  
CJ''#t 4nn :s?rX   objr(   r`   r   c                  t          ||                                j                  r;t          |          x}t          |           x}k    rd| d| }t	          |          |t
          j        u r|                     d          } || _        | S |t
          j	        u r:d|
                                cxk    rdk     rn n|                     |dd          S |                     |d	          S )
z}Wrapper around pandas' set_axis to set object index.

    We can set `copy` / `inplace` based on implementation/version.
    zExpected object of length z, got length: F)deep         r   )axiscopy)rs   )rb   to_native_namespaceIndexlenr   r   CUDFrt   r`   rS   _backend_versionset_axis)rk   r`   rN   expected_len
actual_lenri   s         rV   rd   rd      s    %;;==CDD E

"C
 *J" J" T<SSzSSoo,,,hhEh""	
....1133::::d:::::||E|666<<A<&&&rX   argskwargsc                   |t           j        u r*|                                dk    r | j        |i |ddi}n | j        |i |ddd}t	          d|          S )zXWrapper around pandas' rename so that we can set `copy` based on implementation/version.rq   inplaceF)rt   r   r(   )r   rS   ry   renamer	   )rk   rN   r}   r~   results        rV   r   r      s     ...''))T11T;V;;U;;;TGVG%GGGG &)))rX      )maxsizenative_dtypec                X    t          | t          j                  pt          |           dv S )zR*There is no problem which can't be solved by adding an extra string type* pandas.>   string[python]string[pyarrow_numpy]<StringDtype(na_value=nan)>strstring)rb   pdStringDtyper   r   s    rV   is_dtype_non_pyarrow_stringr      s2    
 lBN33 s<7H7H M 8 rX   versionr   r*   c                   t          |           }|j        }|dv r|                                S |dv r|                                S |dv r|                                S |dv r|                                S |dv r|                                S |dv r|                                S |dv r|                                S |dv r|	                                S |d	v r|
                                S |d
v r|                                S t          |           r|                                S |dv r|                                S t                              |          x}r@|                    d          }|                    d          }|                    ||          S t&                              |          x}r*|                    d          }|                    |          S |                                S )N>   Int64int64>   Int32int32>   Int16int16>   Int8int8>   UInt64uint64>   UInt32uint32>   UInt16uint16>   UInt8uint8>   Float64float64>   Float32float32>   rP   boolean	time_unit	time_zone)r   dtypesr   r   r   r   r   r   r   r   r   r   r   StringBooleanPATTERN_PD_DATETIMEmatchgroupDatetimePATTERN_PD_DURATIONDurationUnknown)r   r   dtyper   match_dt_time_unitdt_time_zonedu_time_units           rV   #non_object_native_to_narwhals_dtyper      s   E^F"""||~~"""||~~"""||~~   {{}}$$$}}$$$}}$$$}}"""||~~&&&~~&&&~~"<00 }}###~~$**5111v ;!'k!:!:#)<<#<#<|\:::$**5111v -!'k!:!:|,,,>>rX   seriesPandasLikeSeries | Nonec                   |j         }|t          j        u r|                                S t          j        j        j        }| dn ||                     d          d          }|dk    r|                                S |dk    r"|t          j
        ur|                                S |dk    r|                                S |                                S )Nemptyd   T)skipnar   )r   r   rx   r   r   apitypesinfer_dtypeheadr   V1Object)r   r   rN   r   inferinferred_dtypes         rV   object_native_to_narwhals_dtyper      s     ^F,,, }}FL$E &WWEE&++c:J:JSW4X4X4XN!!}}  WGJ%>%>}}  }}==??rX   pd.CategoricalDtypec                    |j         }|t          j        u r|                                S | j        rK|t
          j        u rt          |           n| j        j	        }|
                    t          |                    S |                                S rR   )r   r   r   Categoricalorderedr   rx   _cudf_categorical_to_list
categoriesto_listEnumr   )r   r   rN   r   	into_iters        rV   $native_categorical_to_narwhals_dtyper     s     ^F'*!!### 9 !444 &l333(0 	
 {{,Y77888rX   Callable[[], list[Any]]c                     d fd}|S )NrO   	list[Any]c                 Z     j                                                                         S rR   )r   to_arrow	to_pylistr   s   rV   fnz%_cudf_categorical_to_list.<locals>.fn*  s$    &//11;;===rX   )rO   r    )r   r   s   ` rV   r   r   $  s(    > > > > > > IrX   )rf   structdecimalF)allow_objectr   c                  t          |           }t          |           s|                    t                    r>ddlm} t          | d          r|                                 }n| j        } |||          S |dk    rt          | ||          S |dk    rt          | |          S |t          j        u r|j                                        S |rt          d ||          S d}t!          |          )Nr   )native_to_narwhals_dtyper   categoryobjectz;Unreachable code, object dtype should be handled separately)r   is_dtype_pyarrow
startswithCUDF_BASE_DTYPE_PREFIXnarwhals._arrow.utilsr   hasattrr   pyarrow_dtyper   r   r   DASKr   r   r   AssertionError)r   r   rN   r   	str_dtypearrow_native_to_narwhals_dtypepa_dtyperi   s           rV   r   r   3  s(    L!!I%% 	A)=)=>T)U)U 	A	
 	
 	
 	
 	
 	
 <,, 	2$0$9$9$;$;HH#1H--h@@@J3L'>ZZZH2<III,,, ~$$&&& N.tWnMMME  

rX   )ro      r   TypeIs[BaseMaskedDtype]c                    t                      }t          | t          j        j        j                  ot          | d|          du S )z/Return `True` if `dtype` is `"numpy_nullable"`.baseN)r   rb   r   r   
extensionsExtensionDtypegetattr)r   sentinels     rV   is_dtype_numpy_nullabler   X  s@     88ubf/>?? 9vx00D8	
rX   c                z    t          | t          j        j        j                  rddlm} t          | |          S dS )Nr   r   F)rb   r   r   r   r   pandas.core.arrays.maskedr    )r   OldBaseMaskedDtypes     rV   r   r   c  sT     eRV.=>> 	9      e%7888urX   r+   c                j    |t           j        u rdS t          |           rdS t          |           rdndS )zjGet dtype backend for pandas type.

    Matches pandas' `dtype_backend` argument in `convert_dtypes`.
    Npyarrownumpy_nullable)r   rx   r   r   )r   rN   s     rV   get_dtype_backendr   r  sE    
 ,,,t y6u==G4GrX   r   Iterable[Any]Iterator[DTypeBackend]c                     fd| D             S )ziYield a `DTypeBackend` per-dtype.

    Matches pandas' `dtype_backend` argument in `convert_dtypes`.
    c              3  8   K   | ]}t          |          V  d S rR   )r   ).0r   rN   s     rV   	<genexpr>z&iter_dtype_backends.<locals>.<genexpr>  s.      IIe^44IIIIIIrX   r   )r   rN   s    `rV   iter_dtype_backendsr    s      JIII&IIIIrX   TypeIs[pd.ArrowDtype]c                `    t          t          d          ot          | t          j                  S )N
ArrowDtype)r   r   rb   r  r   s    rV   r   r     s#    2|$$IE2=)I)IIrX   r   r   zMapping[type[DType], str]NW_TO_PD_DTYPES_INVARIANTzFloat64[pyarrow]r   r   )r   r   NzFloat32[pyarrow]r   r   Int64[pyarrow]r   r   zInt32[pyarrow]r   r   zInt16[pyarrow]r   r   zInt8[pyarrow]r   r   zUInt64[pyarrow]r   r   zUInt32[pyarrow]r   r   zUInt16[pyarrow]r   r   zUInt8[pyarrow]r   r   zboolean[pyarrow]r   z<Mapping[type[DType], Mapping[DTypeBackend, str | type[Any]]]NW_TO_PD_DTYPES_BACKENDr,   dtype_backendstr | PandasDtypec           	        |dvrd| d}t          |          |j        }|                                 }t                              |          x}r|S t
                              |          x}r||         S t          ||j                  r:|dk    r%dd l}	t          j
         |	j                              S |dk    rdS t          S t          | |j                  rt          |          rut           dk     rjt#          | |j                  rR| j        d	k    rGt'          j        t                     }
d
|
d}d}d| j        d| d| d}t+          |t,                     d	}n| j        }|dk    r| j        x}rd| nd}d| | dS | j        x}rd| nd}d| | dS t          | |j                  r6t          |          rt           dk     rd	}n| j        }|dk    rd| dnd| dS t          | |j                  r,	 dd l}	n$# t4          $ r}d}t5          |          |d }~ww xY wdS t          | |j                  ru|t8          j        u rd}t=          |          t#          | |j                  r0|                                }|                     | j!        d          S d}t          |          t          ||j"        |j#        |j$        |j%        |j&        |j'        f          rtQ          | ||          S d |  }tS          |          )!N>   Nr   r   z;Expected one of {None, 'pyarrow', 'numpy_nullable'}, got: ''r   r   r   r   )r   rL   z*available in 'pandas>=2.0', found version .zhttps://pandas.pydata.org/docs/dev/whatsnew/v2.0.0.html#construction-with-datetime64-or-timedelta64-dtype-with-unsupported-resolutionz`nw.Datetime(time_unit=z)` is only z
Narwhals has fallen back to using `time_unit='ns'` to avoid an error.

Hint: to avoid this warning, consider either:
- Upgrading pandas: zA
- Using a bare `nw.Datetime`, if this precision is not importantz, tz= z
timestamp[z
][pyarrow]z, zdatetime64[]z	duration[ztimedelta64[z/'pyarrow>=13.0.0' is required for `Date` dtype.zdate32[pyarrow]z9Converting to Enum is not supported in narwhals.stable.v1T)r   z9Can not cast / initialize Enum without categories presentzUnknown dtype: )*
ValueErrorr   	base_typer  getr	  
issubclassr   r   r   r  r   r   r   r   rW   PANDAS_VERSIONrb   r   r   _unparse_versionr   UserWarningr   r   DateModuleNotFoundErrorr   r   r   NotImplementedErrorru   CategoricalDtyper   StructArrayListTimeBinaryDecimalnarwhals_to_native_arrow_dtyper   )r   r
  rN   r   ri   r   r  pd_typeinto_pd_typepafound	availablechangelog_urlr   tztz_partr   excrL   s                      rV   narwhals_to_native_dtyper,    s    ???^m^^^oo^F!!I+//	:::w .229===| +M**)V]++ I%%     =---,,,8
v77 6n-- 	+. D
 3
 3
 %11 0eo6M6M 1.AASSSS	 !hXeo X XI X X ,9X X X  c;///LL ?LI%%-2_'<rElblll2GAAgAAAA&+o 5>)r)))B5\575555v77 
n-- 	+. D
 3
 3
  LL ?L 	)) 10000////	

  v{33 !	4     " 	4 	4 	4CC%c**3	4 ! v{33 gj  MC%c***eV[)) 	G3355B&&u'7&FFFIooMLKKMN	

 
 N .e^WMMM
#E
#
#C


s   =H 
H#HH#pd.ArrowDtypec                   t          |          rdt          dk    rY	 dd l}n/# t          $ r"}d|  d|j         }t          |          |d }~ww xY wddlm} t          j         || |                    S d|  d| d| d	}t          |          )
N)r   r   r   zUnable to convert to z! due to the following exception: )r,  zConverting to z+ dtype is not supported for implementation z and version r  )
rW   r  r   ImportErrorri   r   r,  r   r  r  )r   rN   r   r%  r+  ri   _to_arrow_dtypes          rV   r"  r"  %  s     .)) 
>n.F.F	,      	, 	, 	,YYYPSPWYY  c""+		,
 	VUUUUU}__UG<<===	3 	3 	3	3 	3(/	3 	3 	3  c
"
""s   ! 
AAAr   c                    dt          |           v rdS t          |                                           t          |           k    rdS dS )Nr   r  r   r   )r   lowerr  s    rV   int_dtype_mapperr3  :  sF    CJJ
5zzSZZ''w7rX   i  i@B )	)rL   rK   )rL   rJ   )rK   rL   )rK   rJ   )rJ   rL   )rJ   rK   )rI   rL   )rI   rK   )rI   rJ   zGMapping[tuple[UnitCurrent, UnitTarget], tuple[BinOpBroadcast, IntoRhs]]_TIMESTAMP_DATETIME_OP_FACTORrI   r)   currentr-   r   c                    ||k    r| S t                               ||f          x}r|\  }} || |          S d| d}t          |          )Nzunexpected time unit zD, please report an issue at https://github.com/narwhals-dev/narwhals)r4  r  r   )rI   r5  r   itemr   factorri   s          rV   calculate_timestamp_datetimer9  Q  sx     ),00'91EFFFt 
Fr!V}}	3 	3 	3 	3  

rX   ro   )rL   rK   rJ   rI   zMapping[TimeUnit, int]_TIMESTAMP_DATE_FACTORc                2    | t           z  t          |         z  S rR   )r   r:  )rI   r   s     rV   calculate_timestamp_dater<  h  s    !7	!BBBrX   dfr'   column_nameslist[str] | _1DArrayNativeDataFrameT | Anyc                   t          |          | j        d         k    r| j        |k                                    r| S | j        j        j        dk    s&|t          j        u rU|                                dk     r=t          || j        
                                          x}r|| j        dd|f         S 	 | |         S # t          $ r3}t          || j        
                                          x}r|| d}~ww xY w)zsSelect columns by name.

    Prefer this over `df.loc[:, column_names]` as it's
    generally more performant.
    ro   brn   )r'  N)rw   shapecolumnsallr   kindr   rS   ry   r   tolistlocKeyError)r=  r>  rN   errores        rV   select_columns_by_namerL  l  s    <BHQK''RZ<-G,L,L,N,N'	

$$.///++--66 (
@Q@Q@S@STTTT5 	Kvaaao&&,   '
@Q@Q@S@STTTT5 	Qs   7B? ?
C<	.C77C<c                v    | j         t          j        t          j        t          j        hv o| j        j        dk    S )NrP   )re   r   rS   rT   r   r_   r   )rI   s    rV   is_non_nullable_booleanrN    s9     	
!>#79LM	N 	%HNf$rX   r   c                   | t           j        t           j        hv rddl}|S | t           j        u rddl}|S d|  }t          |          )zCReturns numpy or cupy module depending on the given implementation.r   Nz!Expected pandas/modin/cudf, got: )r   rS   rT   numpyrx   cupyr   )rN   npcpri   s       rV   import_array_modulerT    sc    ./1EFFF	,,,	
>n
>
>C


rX   c                      e Zd ZdS )PandasLikeSeriesNamespaceN)__name__
__module____qualname__r   rX   rV   rV  rV    s          rX   rV  drop_null_keysdict[str, bool]c                    dd| ddS )NFT)sortas_indexdropnaobservedr   )rZ  s    rV   make_group_by_kwargsra    s    t~SWXXXrX   r_   pd.Series[Any]	is_nestedseries_classtype[pd.Series[Any]]c                   | j         d         }|rKddlm} t          j         ||t          |                    | j                  } |||| j                  S  |||| j        | j                  S )a`  Broadcast a scalar value from a (one element) Series to match a target index.

    For nested (arrow-backed) types, we rely on
    [`pandas.array`](https://pandas.pydata.org/docs/reference/api/pandas.array.html).

    Arguments:
        native: The native pandas-like Series containing the scalar value to broadcast.
        index: The target index to broadcast to.
        is_nested: Whether the Series has a nested (arrow-backed) dtype.
        series_class: Series class to use for constructing the result.

    Returns:
        A new Series with the scalar value broadcast to match the target index.
    r   )repeatr  )r`   name)r`   r   rh  )rc   r   rg  r   arrayrw   r   rh  )r_   r`   rc  rd  valuerg  pa_arrays          rV   broadcast_series_to_indexrl    s    * KNE E000000 8FF5#e**55V\JJJ|HEDDDD<U&,V[QQQQrX   )rN   r   rO   rP   )rY   r&   rZ   r[   rO   r\   )rk   r(   r`   r   rN   r   rO   r(   )
rk   r(   r}   r   rN   r   r~   r   rO   r(   )r   r   rO   rP   )r   r   r   r   rO   r*   )r   r   r   r   rN   r   rO   r*   )r   r   r   r   rN   r   rO   r*   )r   r   rO   r   )
r   r   r   r   rN   r   r   rP   rO   r*   )r   r   rO   r   )r   r   rN   r   rO   r+   )r   r   rN   r   rO   r   )r   r   rO   r  )
r   r,   r
  r+   rN   r   r   r   rO   r  )r   r,   rN   r   r   r   rO   r-  )r   r   rO   r   )rI   r)   r5  r-   r   r-   rO   r)   )rI   r)   r   r-   rO   r)   )r=  r'   r>  r?  rN   r   rO   r@  )rI   r&   rO   rP   )rN   r   rO   r   )rZ  rP   rO   r[  )
r_   rb  r`   r   rc  rP   rd  re  rO   rb  )
__future__r   	functoolsoperatorretypingr   r   r   r   r   r	   rP  rR  pandasr   narwhals._compliantr
   narwhals._constantsr   r   r   r   r   r   narwhals._exceptionsr   narwhals._utilsr   r   r   r   r   r   r   narwhals.exceptionsr   collections.abcr   r   r   r   r   r   r%  pandas._typingr   PandasDtypepandas.core.dtypes.dtypesr    typing_extensionsr!   r"   narwhals._durationr#   narwhals._pandas_like.exprr$   r^   r&   narwhals._pandas_like.typingr'   r(   r)   narwhals.dtypesr*   narwhals.typingr+   r,   r-   r.   r/   r1   __annotations__r2   intr3   r4   rS   rx   rT   PANDAS_LIKE_IMPLEMENTATIONPD_DATETIME_RGXcompileVERBOSEr   PD_DURATION_RGXr   r@   
ALIAS_DICTrM   ry   r  NUMPY_VERSIONrW   rj   rd   r   	lru_cacher   r   r   r   r   r   r   r   r   r  r   MAINr   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r	  r,  r"  r3  floordivmulr4  r9  r:  r<  rL  rN  rT  rV  ra  rl  r   rX   rV   <module>r     s   " " " " " " "      				 G G G G G G G G G G G G G G G G         4 4 4 4 4 4                / . . . . .                  + * * * * * ;;;;;;;;;;      33333399999933333333//////999999======         
 &%%%%%KKKKKKKKKKKKGG>222E%K%%%%$J$$$$ (#sS 9N9999G  
 !bj"*== 
 !bj"*==  '
!      U##
		
				


9 9
      &7799
 b!!K K K K   B' ' ' '.
* 
* 
* 
* R   
 
 
 ! 
 R   # # # ! #L   .        	 	 	 	 7             F ))++v55
 
 
 
 
   	H 	H 	H 	HJ J J J R   J J J ! J 
	
 

M88      N%# 
 N%# 
 L.'QXYY
L.'QXYY
L.'QXYY
K_fUU
M$" 
 M$" 
 M$" 
 L.'QXYY
N%# ?$Y  $ $ $ $Ne e e eP# # # #*    $e,$i0<!34$e,<!34<',.,.,.
 
          

	
	2 2     C C C C   :       T S S S S 45G5L M S S SY Y Y YR R R R R RrX   