
    MhC                    b   S SK Jr  S SKrS SKJr  S SKrS SKJr  S SK	J
r
  S SKJr  S SKJr  S SKJs  Jr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  \(       a  S SKJr  S SKJ r   S SK!J"r"  SS jr#\" \S   SSS.-  5            S       SS jj5       r$SSS jjr% S       SS jjr&g)    )annotationsN)TYPE_CHECKING)Appender)is_list_like)concat_compat)notna)
MultiIndex)concat)tile_compat)_shared_docs)
to_numeric)Hashable)AnyArrayLike)	DataFramec                    U bV  [        U 5      (       d  U /$ [        U[        5      (       a#  [        U [        5      (       d  [	        U S35      e[        U 5      $ / $ )Nz7 must be a list of tuples when columns are a MultiIndex)r   
isinstancer	   list
ValueError)arg_varsvariablecolumnss      J/var/www/html/env/lib/python3.13/site-packages/pandas/core/reshape/melt.pyensure_list_varsr      s]    H%%:,,Z$5O5O*ST  >!	    meltzpd.melt(df, zDataFrame.melt)callerotherc                   X@R                   ;   a  [        SU S35      e[        USU R                   5      nUS Ln[        USU R                   5      nU(       d  U(       a  Ub  U R                   R                  U5      nOU R                   nX-   n	UR	                  U	5      n
U
S:H  nUR                  5       (       a6  [        X5       VVs/ s H  u  pU(       d  M  UPM     nnn[        SU 35      eU(       a(  U R                  S S 2[        R                  " U
5      4   n O!U R                  5       n OU R                  5       n Ub   U R                   R                  U5      U l         Uc  [        U R                   [        5      (       a  [        U R                   R                  5      [        [!        U R                   R                  5      5      :X  a  U R                   R                  nO[#        [        U R                   R                  5      5       Vs/ s H  nSU 3PM
     nnOTU R                   R$                  b  U R                   R$                  OS/nO#['        U5      (       a  [        S	U< S
35      eU/nU R(                  u  nnU[        U5      -
  n0 nU H  nU R+                  U5      n[        UR,                  [.        R,                  5      (       dC  US:  a  [1        U/U-  SS9UU'   MV  [3        U5      " / UR$                  UR,                  S9UU'   M  [.        R4                  " UR6                  U5      UU'   M     X-   U/-   nU R(                  S   S:  aq  [        S U R8                   5       5      (       dP  [1        [#        U R(                  S   5       Vs/ s H  oR                  S S 2U4   PM     sn5      R:                  UU'   OU R6                  R=                  S5      UU'   [?        U5       H3  u  nnU R                   RA                  U5      RC                  U5      UU'   M5     U RE                  UUS9nU(       d  [G        U RH                  U5      Ul$        U$ s  snnf s  snf s  snf )Nzvalue_name (z3) cannot match an element in the DataFrame columns.id_vars
value_varszFThe following id_vars or value_vars are not present in the DataFrame: 	variable_r   z	var_name=z must be a scalar.r   T)ignore_index)namedtype   c              3     #    U  H7  n[        U[        R                  5      (       + =(       a    UR                  v   M9     g 7f)N)r   npr%   _supports_2d).0dts     r   	<genexpr>melt.<locals>.<genexpr>z   s-      &CORJr288$$88<s   ?AFr   )%r   r   r   get_level_valuesget_indexer_foranyzipKeyErrorilocalgosuniquecopyr   r	   lennamessetranger$   r   shapepopr%   r(   r
   typetile_valuesdtypesvaluesravel	enumerate_get_level_valuesrepeat_constructorr   index)framer   r    var_name
value_name	col_levelr#   value_vars_was_not_nonelevellabelsidxmissinglab	not_foundmissing_labelsinum_rowsKnum_cols_adjustedmdatacolid_datamcolumnsresults                           r   r   r   +   s    ]]":, '% %
 	
 w	5==AG(4!*lEMMJJ* MM229=EMME%##F+);;==*-f*>*>)*>   ""0!13  #JJq%,,s"334EJJLE

66yAemmZ005==&&'3s5==3F3F/G+HH ==..5:3u}}?R?R;S5TU5TisO5TU ',mm&8&8&D""*H 
h		IH;&89:::++KHaCL(*,E))C.'--22 1$#WI0A$APTUc
 "']2GLLVc
2CDE#J  !ZL0H{{1~# &CH<<& # # #',U[[^'<='<!ZZ1'<=

& 	j "MM//4jH%3]]44Q7>>xHc
 & x8F"5;;0ABMG. V@ >s   QQQ#Q(c                X   0 n/ n[        5       n[        [        [        UR	                  5       5      5      5      nUR                  5        Hl  u  px[        U5      U:w  a  [        S5      eU V	s/ s H  oU	   R                  PM     n
n	[        U
5      X7'   UR                  U5        UR                  U5      nMn     [        U R                  R                  U5      5      nU H(  n	[        R                  " X	   R                  U5      X9'   M*     U(       a|  [        R                   " [        X4S      5      ["        S9nU H  nU[%        X=   5      -  nM     UR'                  5       (       d'  UR                  5        VVs0 s H
  u  pXU   _M     nnnU R)                  X;U-   S9$ s  sn	f s  snnf )a   
Reshape wide-format data to long. Generalized inverse of DataFrame.pivot.

Accepts a dictionary, ``groups``, in which each key is a new column name
and each value is a list of old column names that will be "melted" under
the new column name as part of the reshape.

Parameters
----------
data : DataFrame
    The wide-format DataFrame.
groups : dict
    {new_name : list_of_columns}.
dropna : bool, default True
    Do not include columns whose entries are all NaN.

Returns
-------
DataFrame
    Reshaped DataFrame.

See Also
--------
melt : Unpivot a DataFrame from wide to long format, optionally leaving
    identifiers set.
pivot : Create a spreadsheet-style pivot table as a DataFrame.
DataFrame.pivot : Pivot without aggregation that can handle
    non-numeric data.
DataFrame.pivot_table : Generalization of pivot that can handle
    duplicate values for one index/column pair.
DataFrame.unstack : Pivot based on the index values instead of a
    column.
wide_to_long : Wide panel to long format. Less flexible but more
    user-friendly than melt.

Examples
--------
>>> data = pd.DataFrame({'hr1': [514, 573], 'hr2': [545, 526],
...                      'team': ['Red Sox', 'Yankees'],
...                      'year1': [2007, 2007], 'year2': [2008, 2008]})
>>> data
   hr1  hr2     team  year1  year2
0  514  545  Red Sox   2007   2008
1  573  526  Yankees   2007   2008

>>> pd.lreshape(data, {'year': ['year1', 'year2'], 'hr': ['hr1', 'hr2']})
      team  year   hr
0  Red Sox  2007  514
1  Yankees  2007  573
2  Red Sox  2008  545
3  Yankees  2008  526
z$All column lists must be same lengthr   )r%   r/   )r;   r9   nextiterrC   itemsr   rA   r   appendunionr   r   
differencer(   r@   onesboolr   allrH   )datagroupsdropnarZ   
pivot_colsall_colsrX   targetr:   r[   	to_concatid_colsmaskckvs                   r   lreshaperu      sg   j EJ!eHDfmmo&'(Au:?CDD278%3#Y&&%	8%i0&!>>%( ( 4<<**845GWWTY..2
  wws5A/0=AE%(O#D xxzz,1KKM:MDAQ$ZME:Uj,@AA# 9 ;s   -F!;F&c                   SS jnS	S jn[        U5      (       d  U/nO[        U5      nU R                  R                  U5      R	                  5       (       a  [        S5      e[        U5      (       d  U/nO[        U5      nX   R                  5       R	                  5       (       a  [        S5      e/ n/ n	U H6  n
U" X
XE5      nU	R                  U5        UR                  U" X
X#X5      5        M8     [        USS9nU R                  R                  U	5      nX   n[        U5      S:X  a   UR                  U5      R                  U5      $ UR                  UR                  5       US9R                  X#/-   5      $ )
a(  
Unpivot a DataFrame from wide to long format.

Less flexible but more user-friendly than melt.

With stubnames ['A', 'B'], this function expects to find one or more
group of columns with format
A-suffix1, A-suffix2,..., B-suffix1, B-suffix2,...
You specify what you want to call this suffix in the resulting long format
with `j` (for example `j='year'`)

Each row of these wide variables are assumed to be uniquely identified by
`i` (can be a single column name or a list of column names)

All remaining variables in the data frame are left intact.

Parameters
----------
df : DataFrame
    The wide-format DataFrame.
stubnames : str or list-like
    The stub name(s). The wide format variables are assumed to
    start with the stub names.
i : str or list-like
    Column(s) to use as id variable(s).
j : str
    The name of the sub-observation variable. What you wish to name your
    suffix in the long format.
sep : str, default ""
    A character indicating the separation of the variable names
    in the wide format, to be stripped from the names in the long format.
    For example, if your column names are A-suffix1, A-suffix2, you
    can strip the hyphen by specifying `sep='-'`.
suffix : str, default '\\d+'
    A regular expression capturing the wanted suffixes. '\\d+' captures
    numeric suffixes. Suffixes with no numbers could be specified with the
    negated character class '\\D+'. You can also further disambiguate
    suffixes, for example, if your wide variables are of the form A-one,
    B-two,.., and you have an unrelated column A-rating, you can ignore the
    last one by specifying `suffix='(!?one|two)'`. When all suffixes are
    numeric, they are cast to int64/float64.

Returns
-------
DataFrame
    A DataFrame that contains each stub name as a variable, with new index
    (i, j).

See Also
--------
melt : Unpivot a DataFrame from wide to long format, optionally leaving
    identifiers set.
pivot : Create a spreadsheet-style pivot table as a DataFrame.
DataFrame.pivot : Pivot without aggregation that can handle
    non-numeric data.
DataFrame.pivot_table : Generalization of pivot that can handle
    duplicate values for one index/column pair.
DataFrame.unstack : Pivot based on the index values instead of a
    column.

Notes
-----
All extra variables are left untouched. This simply uses
`pandas.melt` under the hood, but is hard-coded to "do the right thing"
in a typical case.

Examples
--------
>>> np.random.seed(123)
>>> df = pd.DataFrame({"A1970" : {0 : "a", 1 : "b", 2 : "c"},
...                    "A1980" : {0 : "d", 1 : "e", 2 : "f"},
...                    "B1970" : {0 : 2.5, 1 : 1.2, 2 : .7},
...                    "B1980" : {0 : 3.2, 1 : 1.3, 2 : .1},
...                    "X"     : dict(zip(range(3), np.random.randn(3)))
...                   })
>>> df["id"] = df.index
>>> df
  A1970 A1980  B1970  B1980         X  id
0     a     d    2.5    3.2 -1.085631   0
1     b     e    1.2    1.3  0.997345   1
2     c     f    0.7    0.1  0.282978   2
>>> pd.wide_to_long(df, ["A", "B"], i="id", j="year")
... # doctest: +NORMALIZE_WHITESPACE
                X  A    B
id year
0  1970 -1.085631  a  2.5
1  1970  0.997345  b  1.2
2  1970  0.282978  c  0.7
0  1980 -1.085631  d  3.2
1  1980  0.997345  e  1.3
2  1980  0.282978  f  0.1

With multiple id columns

>>> df = pd.DataFrame({
...     'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
...     'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
...     'ht1': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
...     'ht2': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
... })
>>> df
   famid  birth  ht1  ht2
0      1      1  2.8  3.4
1      1      2  2.9  3.8
2      1      3  2.2  2.9
3      2      1  2.0  3.2
4      2      2  1.8  2.8
5      2      3  1.9  2.4
6      3      1  2.2  3.3
7      3      2  2.3  3.4
8      3      3  2.1  2.9
>>> l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age')
>>> l
... # doctest: +NORMALIZE_WHITESPACE
                  ht
famid birth age
1     1     1    2.8
            2    3.4
      2     1    2.9
            2    3.8
      3     1    2.2
            2    2.9
2     1     1    2.0
            2    3.2
      2     1    1.8
            2    2.8
      3     1    1.9
            2    2.4
3     1     1    2.2
            2    3.3
      2     1    2.3
            2    3.4
      3     1    2.1
            2    2.9

Going from long back to wide just takes some creative use of `unstack`

>>> w = l.unstack()
>>> w.columns = w.columns.map('{0[0]}{0[1]}'.format)
>>> w.reset_index()
   famid  birth  ht1  ht2
0      1      1  2.8  3.4
1      1      2  2.9  3.8
2      1      3  2.2  2.9
3      2      1  2.0  3.2
4      2      2  1.8  2.8
5      2      3  1.9  2.4
6      3      1  2.2  3.3
7      3      2  2.3  3.4
8      3      3  2.1  2.9

Less wieldy column names are also handled

>>> np.random.seed(0)
>>> df = pd.DataFrame({'A(weekly)-2010': np.random.rand(3),
...                    'A(weekly)-2011': np.random.rand(3),
...                    'B(weekly)-2010': np.random.rand(3),
...                    'B(weekly)-2011': np.random.rand(3),
...                    'X' : np.random.randint(3, size=3)})
>>> df['id'] = df.index
>>> df # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
   A(weekly)-2010  A(weekly)-2011  B(weekly)-2010  B(weekly)-2011  X  id
0        0.548814        0.544883        0.437587        0.383442  0   0
1        0.715189        0.423655        0.891773        0.791725  1   1
2        0.602763        0.645894        0.963663        0.528895  1   2

>>> pd.wide_to_long(df, ['A(weekly)', 'B(weekly)'], i='id',
...                 j='year', sep='-')
... # doctest: +NORMALIZE_WHITESPACE
         X  A(weekly)  B(weekly)
id year
0  2010  0   0.548814   0.437587
1  2010  1   0.715189   0.891773
2  2010  1   0.602763   0.963663
0  2011  0   0.544883   0.383442
1  2011  1   0.423655   0.791725
2  2011  1   0.645894   0.528895

If we have many columns, we could also use a regex to find our
stubnames and pass that list on to wide_to_long

>>> stubnames = sorted(
...     set([match[0] for match in df.columns.str.findall(
...         r'[A-B]\(.*\)').values if match != []])
... )
>>> list(stubnames)
['A(weekly)', 'B(weekly)']

All of the above examples have integers as suffixes. It is possible to
have non-integers as suffixes.

>>> df = pd.DataFrame({
...     'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
...     'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
...     'ht_one': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
...     'ht_two': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
... })
>>> df
   famid  birth  ht_one  ht_two
0      1      1     2.8     3.4
1      1      2     2.9     3.8
2      1      3     2.2     2.9
3      2      1     2.0     3.2
4      2      2     1.8     2.8
5      2      3     1.9     2.4
6      3      1     2.2     3.3
7      3      2     2.3     3.4
8      3      3     2.1     2.9

>>> l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age',
...                     sep='_', suffix=r'\w+')
>>> l
... # doctest: +NORMALIZE_WHITESPACE
                  ht
famid birth age
1     1     one  2.8
            two  3.4
      2     one  2.9
            two  3.8
      3     one  2.2
            two  2.9
2     1     one  2.0
            two  3.2
      2     one  1.8
            two  2.8
      3     one  1.9
            two  2.4
3     1     one  2.2
            two  3.3
      2     one  2.3
            two  3.4
      3     one  2.1
            two  2.9
c                    S[         R                  " U5       [         R                  " U5       U S3nU R                  U R                  R                  R	                  U5         $ )N^$)reescaper   strmatch)dfstubsepsuffixregexs        r   get_var_names#wide_to_long.<locals>.get_var_names  sL    RYYt_%biin%5fXQ?zz"**....u566r   c                "   [        U UUUR                  U5      US9nXc   R                  R                  [        R
                  " X-   5      SSS9Xc'    [        Xc   5      Xc'   UR                  X#/-   5      $ ! [        [        [        4 a     N+f = f)N)r   r    rL   rK    T)r   )r   rstripr|   replacerz   r{   r   	TypeErrorr   OverflowError	set_index)r~   r   rV   jr    r   newdfs          r   	melt_stubwide_to_long.<locals>.melt_stub  s    !{{3'
 8<<''		$*(=r'N	!%(+EH
 q3w''	 :}5 		s   A6 6BBz,stubname can't be identical to a column namez3the id variables need to uniquely identify each rowr&   )axis)on)r   r|   r   r|   r   r|   )r   r|   r   r|   )r   r   r   isinr2   r   
duplicatedextendrc   r
   re   r9   r   joinmergereset_index)r~   	stubnamesrV   r   r   r   r   r   _meltedvalue_vars_flattenedr   	value_varmeltedr   news                  r   wide_to_longr      sO   \7(& 	""K	O		zzy!%%''GHH??CG	uNOOG!"C8	##I.y1@A 
 G!$Fjj##$89G
+C
1v{}}Q$$V,,yy++-!y4>>q3wGGr   )r   r|   returnr   )NNNvalueNT)rJ   r   rL   r   r#   rg   r   r   )T)ri   r   rj   dictrk   rg   r   r   )r   z\d+)r~   r   r   r|   r   r|   r   r   )'
__future__r   rz   typingr   numpyr(   pandas.util._decoratorsr   pandas.core.dtypes.commonr   pandas.core.dtypes.concatr   pandas.core.dtypes.missingr   pandas.core.algorithmscore
algorithmsr6   pandas.core.indexes.apir	   pandas.core.reshape.concatr
   pandas.core.reshape.utilr   pandas.core.shared_docsr   pandas.core.tools.numericr   collections.abcr   pandas._typingr   pandasr   r   r   ru   r    r   r   <module>r      s    " 	    , 2 3 , & & . - 0 0 0(+  
,v
NEU!V
VW "^^
 ^ ^ ^ X^BMBb BHcHcH),cH;>cHcHr   