
    Kh                        S r SSKrSSKrSSKJr  SSKJs  Jr  SSK	J
r
  SSKJr  / SQrS r\
" \5      S 5       rS rS	 rS
 rS rS7S jrS7S jrS8S jrS rS rS9S jrS:S jrS;S jr  S<S jr\
" \5        S=S j5       rS8S jr\
" \5      S:S j5       rS:S jr S r!\
" \!5      S 5       r"S r#\
" \#5      S 5       r$  S<S jr%\
" \%5        S>S j5       r&S;S jr'\
" \'5      S;S  j5       r(S8S! jr)\
" \)5      S?S" j5       r*S@S# jr+S$ r,  SAS% jr-\
" \-5      SBS& j5       r.  SCS' jr/\
" \/5        SDS( j5       r0S) r1\
" \15      S* 5       r2S;S+ jr3\
" \35      SES, j5       r4S- r5\
" \55      S. 5       r6  S<S/ jr7\
" \75        SFS0 j5       r8 SAS1 jr9\
" \95      SGS2 j5       r:  SHS3 jr;\
" \;5        SIS4 j5       r<  S<S5 jr=\
" \=5        SJS6 j5       r>C
g)Kz
Collection of utilities to manipulate structured arrays.

Most of these functions were initially implemented by John Hunter for
matplotlib.  They have been rewritten and extended for convenience.

    N)array_function_dispatch)_is_string_like)append_fieldsapply_along_fieldsassign_fields_by_namedrop_fieldsfind_duplicatesflatten_descrget_fieldstructure	get_namesget_names_flatjoin_bymerge_arraysrec_append_fieldsrec_drop_fieldsrec_joinrecursive_fill_fieldsrename_fieldsrepack_fieldsrequire_fieldsstack_arraysstructured_to_unstructuredunstructured_to_structuredc                     X4$ N )inputoutputs     H/var/www/html/env/lib/python3.13/site-packages/numpy/lib/recfunctions.py!_recursive_fill_fields_dispatcherr       s
    ?    c                     UR                   nUR                   H?  n X   nUR                   R                  b  [        XAU   5        M/  XAU   S[	        U5      & MA     U$ ! [         a     MR  f = f)a5  
Fills fields from output with fields from input,
with support for nested structures.

Parameters
----------
input : ndarray
    Input array.
output : ndarray
    Output array.

Notes
-----
* `output` should be at least the same size as `input`

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', np.int64), ('B', np.float64)])
>>> b = np.zeros((3,), dtype=a.dtype)
>>> rfn.recursive_fill_fields(a, b)
array([(1, 10.), (2, 20.), (0,  0.)], dtype=[('A', '<i8'), ('B', '<f8')])

N)dtypenames
ValueErrorr   len)r   r   newdtypefieldcurrents        r   r   r       sr    6 ||H	lG ==*!'%=9+25M-3w<(   M  		s   A
A,+A,c                    ^  T R                   c  ST 4/$ U 4S jT R                    5       nU VVs/ s H"  u  p#[        U5      S:X  a  UOUS   U4US   4PM$     snn$ s  snnf )a5  
Produce a list of name/dtype pairs corresponding to the dtype fields

Similar to dtype.descr, but the second item of each tuple is a dtype, not a
string. As a result, this handles subarray dtypes

Can be passed to the dtype constructor to reconstruct the dtype, noting that
this (deliberately) discards field offsets.

Examples
--------
>>> import numpy as np
>>> dt = np.dtype([(('a', 'A'), np.int64), ('b', np.double, 3)])
>>> dt.descr
[(('a', 'A'), '<i8'), ('b', '<f8', (3,))]
>>> _get_fieldspec(dt)
[(('a', 'A'), dtype('int64')), ('b', dtype(('<f8', (3,))))]

 c              3   D   >#    U  H  oTR                   U   4v   M     g 7fr   )fields.0namer#   s     r   	<genexpr>!_get_fieldspec.<locals>.<genexpr>`   s     Ed+,s       r   )r$   r&   )r#   r-   r0   fs   `   r   _get_fieldspecr5   H   so    ( {{U}EE "
! Vq[TqtTlAaD9!
 	
 
s   )Ac           	          / nU R                   nU HL  nX   nUR                   b'  UR                  U[        [        U5      5      45        M;  UR                  U5        MN     [        U5      $ )a  
Returns the field names of the input datatype as a tuple. Input datatype
must have fields otherwise error is raised.

Parameters
----------
adtype : dtype
    Input datatype

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> rfn.get_names(np.empty((1,), dtype=[('A', int)]).dtype)
('A',)
>>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)]).dtype)
('A', 'B')
>>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
>>> rfn.get_names(adtype)
('a', ('b', ('ba', 'bb')))
)r$   appendtupler   adtype	listnamesr$   r0   r)   s        r   r   r   h   se    , ILLE,==$dE)G*<$=>?T"  r!   c                     / nU R                   nU HA  nUR                  U5        X   nUR                   c  M'  UR                  [        U5      5        MC     [	        U5      $ )aU  
Returns the field names of the input datatype as a tuple. Input datatype
must have fields otherwise error is raised.
Nested structure are flattened beforehand.

Parameters
----------
adtype : dtype
    Input datatype

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> rfn.get_names_flat(np.empty((1,), dtype=[('A', int)]).dtype) is None
False
>>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', str)]).dtype)
('A', 'B')
>>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
>>> rfn.get_names_flat(adtype)
('a', 'b', 'ba', 'bb')
)r$   r7   extendr   r8   r9   s        r   r   r      s[    . ILLE,==$^G45	 
 r!   c                     U R                   nUc  SU 44$ / nU HO  nU R                  U   u  pEUR                   b  UR                  [        U5      5        M=  UR	                  X445        MQ     [        U5      $ )a;  
Flatten a structured data-type description.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> ndtype = np.dtype([('a', '<i4'), ('b', [('ba', '<f8'), ('bb', '<i4')])])
>>> rfn.flatten_descr(ndtype)
(('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))

r+   )r$   r-   r=   r
   r7   r8   )ndtyper$   descrr(   typ_s         r   r
   r
      sr     LLE}VE}}U+HSyy$]3/0e\*  U|r!   c                 p   / nU(       a.  U  H'  nUR                  [        UR                  5      5        M)     OjU  Hd  nUR                  nUR                  b5  [	        UR                  5      S:X  a  UR                  [        U5      5        MQ  UR                  SU45        Mf     [        R                  " U5      $ )N   r+   )r=   r
   r#   r$   r&   r5   r7   np)	seqarraysflattenr'   ar)   s        r   
_zip_dtyperI      s    HAOOM!''23  AggG}}(S-?1-Dw 78W.  88Hr!   c                 (    [        XS9R                  $ )z
Combine the dtype description of a series of arrays.

Parameters
----------
seqarrays : sequence of arrays
    Sequence of arrays
flatten : {boolean}, optional
    Whether to collapse nested descriptions.
rG   )rI   r@   )rF   rG   s     r   
_zip_descrrL      s     i1777r!   c                 `   Uc  0 nU R                   nU H  nX   nUR                   b.  U(       a  U/X$'   O/ X$'   UR                  [        XTU5      5        MB  [        UR	                  U/ 5      =(       d    / 5      nU(       a  UR                  U5        O
U(       a  U/nU=(       d    / X$'   M     U$ )a)  
Returns a dictionary with fields indexing lists of their parent fields.

This function is used to simplify access to fields nested in other fields.

Parameters
----------
adtype : np.dtype
    Input datatype
lastname : optional
    Last processed field name (used internally during recursion).
parents : dictionary
    Dictionary of parent fields (used internally during recursion).

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> ndtype =  np.dtype([('A', int),
...                     ('B', [('BA', int),
...                            ('BB', [('BBA', int), ('BBB', int)])])])
>>> rfn.get_fieldstructure(ndtype)
... # XXX: possible regression, order of BBA and BBB is swapped
{'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}

)r$   updater   listgetr7   )r:   lastnameparentsr$   r0   r)   
lastparents          r   r   r      s    6 LLE,==$!) "NN-gWEFw{{8R8>B@J!!(+&\
&,"GM  Nr!   c              #      #    U  HD  n[        U[        R                  5      (       a  [        [	        U5      5       Sh  vN   M@  Uv   MF     g N7f)zi
Returns an iterator of concatenated fields from a sequence of arrays,
collapsing any nested structure.

N)
isinstancerE   void_izip_fields_flatr8   iterableelements     r   rW   rW     s<      grww''(w888M	 8s   <AAAc              #   <  #    U  H  n[        US5      (       a*  [        U[        5      (       d  [        U5       Sh  vN   M>  [        U[        R
                  5      (       a-  [        [        U5      5      S:X  a  [        U5       Sh  vN   M  Uv   M     g N[ N7f)zH
Returns an iterator of concatenated fields from a sequence of arrays.

__iter__NrD   )hasattrrU   str_izip_fieldsrE   rV   r&   r8   rX   s     r   r_   r_      sw     
 GZ((w,,#G,,,))c%..AQ.F#G,,,M  - -s"   :BBABB	BBc              #      #    U(       a  [         nO[        n[        R                  " U SU06 H  n[	        U" U5      5      v   M     g7f)a  
Returns an iterator of concatenated items from a sequence of arrays.

Parameters
----------
seqarrays : sequence of arrays
    Sequence of arrays.
fill_value : {None, integer}
    Value used to pad shorter iterables.
flatten : {True, False},
    Whether to
	fillvalueN)rW   r_   	itertoolszip_longestr8   )rF   
fill_valuerG   zipfunctups        r   _izip_recordsrg   0  s>      #$$iF:FGCL!! Gs   AAc                    [        U [        R                  5      (       d  SnU(       a(  U(       a  U R                  [        R
                  5      n U $ [        R                  " U 5      n U(       a  U R                  [        R                  5      n U $ )zt
Private function: return a recarray, a ndarray, a MaskedArray
or a MaskedRecords depending on the input parameters
F)	rU   maMaskedArrayviewmrecMaskedRecordsfilledrE   recarray)r   usemask
asrecarrays      r   _fix_outputrr   H  se    
 fbnn--[[!3!34F
 M 6"[[-FMr!   c                     U R                   R                  nU R                  U R                  U R                  pTnU=(       d    0 R                  5        H  u  pgXb;   d  M  XuU'   XsU   XF   '   M     U $ )zd
Update the fill_value and masked data of `output`
from the default given in a dictionary defaults.
)r#   r$   datamaskrd   items)r   defaultsr$   rt   ru   rd   kvs           r   _fix_defaultsrz   Y  sf    
 LLE &V[[&:K:KT>r((*:qM GDG + Mr!   c                     U $ r   r   )rF   rd   rG   rp   rq   s        r   _merge_arrays_dispatcherr|   g  s    r!   c           
      l	   [        U 5      S:X  a  [        R                  " U S   5      n [        U [        R                  [        R
                  45      (       a  U R                  nUR                  c  [        R                  " SU4/5      nU(       a  [        U 4SS9U:X  aw  U R                  5       n U(       a)  U(       a  [        R                  nO9[        R                  nO(U(       a  [        R                  nO[        R                  nU R                  XVS9$ U 4n O&U  Vs/ s H  n[        R                  " U5      PM     n n[!        S U  5       5      n[#        U5      n	[        XS9n
/ n/ nU(       Ga  [%        X5       GHi  u  pX-
  nUR                  5       R'                  5       n[        R(                  " U5      R                  5       nU(       a  [        R*                  " XR                  5      n[        U[        R                  [        R
                  45      (       an  [        UR                  5      S:X  a  UR-                  5       S   nSnOD[        R.                  " UUR                  SS	9n[        R0                  " S
UR                  S9nOSnSnUR3                  [4        R6                  " UU/U-  5      5        UR3                  [4        R6                  " UW/U-  5      5        GMl     [!        [9        XS95      n[        R.                  " [        R:                  " UXS9[=        [9        XS95      S9nU(       a  UR                  [        R                  5      nU$ [%        X5       H  u  pX-
  nUR                  5       R'                  5       nU(       a  [        R*                  " XR                  5      n[        U[        R                  [        R
                  45      (       aM  [        UR                  5      S:X  a  UR-                  5       S   nO#[        R.                  " UUR                  SS	9nOSnUR3                  [4        R6                  " UU/U-  5      5        M     [        R:                  " [!        [9        XS95      XS9nU(       a  UR                  [        R                  5      nU$ s  snf )a  
Merge arrays field by field.

Parameters
----------
seqarrays : sequence of ndarrays
    Sequence of arrays
fill_value : {float}, optional
    Filling value used to pad missing data on the shorter arrays.
flatten : {False, True}, optional
    Whether to collapse nested fields.
usemask : {False, True}, optional
    Whether to return a masked array or not.
asrecarray : {False, True}, optional
    Whether to return a recarray (MaskedRecords) or not.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])))
array([( 1, 10.), ( 2, 20.), (-1, 30.)],
      dtype=[('f0', '<i8'), ('f1', '<f8')])

>>> rfn.merge_arrays((np.array([1, 2], dtype=np.int64),
...         np.array([10., 20., 30.])), usemask=False)
 array([(1, 10.0), (2, 20.0), (-1, 30.0)],
         dtype=[('f0', '<i8'), ('f1', '<f8')])
>>> rfn.merge_arrays((np.array([1, 2]).view([('a', np.int64)]),
...               np.array([10., 20., 30.])),
...              usemask=False, asrecarray=True)
rec.array([( 1, 10.), ( 2, 20.), (-1, 30.)],
          dtype=[('a', '<i8'), ('f1', '<f8')])

Notes
-----
* Without a mask, the missing value will be filled with something,
  depending on what its corresponding type:

  * ``-1``      for integers
  * ``-1.0``    for floating point numbers
  * ``'-'``     for characters
  * ``'-1'``    for strings
  * ``True``    for boolean values
* XXX: I just obtained these values empirically
rD   r   Nr+   TrK   )r#   typec              3   8   #    U  H  oR                   v   M     g 7fr   )size)r/   rH   s     r   r1   merge_arrays.<locals>.<genexpr>  s     ,)Q&&)s   )r#   ndmin)rD   r#   )r#   count)ru   )r&   rE   
asanyarrayrU   ndarrayrV   r#   r$   rI   ravelrl   rm   ri   rj   ro   rk   r8   maxzip	__array__getmaskarray_check_fill_valueitemarrayonesr7   rb   chainrg   fromiterrO   )rF   rd   rG   rp   rq   seqdtypeseqtype_msizes	maxlengthr'   seqdataseqmaskrH   n	nbmissingrt   ru   fvalfmskr   s                        r   r   r   l  sr   d 	I!MM)A,/	)bjj"''233??>>!xx"h 01H*i\4@HL!)I"00G nnG++**>>>??"I 2;;2R]]2&	;,),,EE
I)5HGG)+FQ"I779&&(D??1%++-D--j''BdRZZ$9::4::!+#yy{1~#!xxAGG1E!wwt4::>NN9??4$)1CDENN9??4$)1CDE) ,, ]7<="++d(L#M'$KLN[[!3!34F* M% )+FQ"I779&&(D--j''BdRZZ$9::4::!+#yy{1~!xxAGG1ENN9??4$)1CDE , U=#JK#+>[[-FMu <s    R1c                     U 4$ r   r   )base
drop_namesrp   rq   s       r   _drop_fields_dispatcherr     	    7Nr!   c                    ^ [        U5      (       a  U/nO[        U5      nU4S jmT" U R                  U5      n[        R                  " U R
                  US9n[        X5      n[        XRUS9$ )a  
Return a new array with fields in `drop_names` dropped.

Nested fields are supported.

Parameters
----------
base : array
    Input array
drop_names : string or sequence
    String or sequence of strings corresponding to the names of the
    fields to drop.
usemask : {False, True}, optional
    Whether to return a masked array or not.
asrecarray : string or sequence, optional
    Whether to return a recarray or a mrecarray (`asrecarray=True`) or
    a plain ndarray or masked array with flexible dtype. The default
    is False.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
...   dtype=[('a', np.int64), ('b', [('ba', np.double), ('bb', np.int64)])])
>>> rfn.drop_fields(a, 'a')
array([((2., 3),), ((5., 6),)],
      dtype=[('b', [('ba', '<f8'), ('bb', '<i8')])])
>>> rfn.drop_fields(a, 'ba')
array([(1, (3,)), (4, (6,))], dtype=[('a', '<i8'), ('b', [('bb', '<i8')])])
>>> rfn.drop_fields(a, ['ba', 'bb'])
array([(1,), (4,)], dtype=[('a', '<i8')])
c                    > U R                   n/ nU HR  nX   nXA;   a  M  UR                   b%  T" XQ5      nU(       a  UR                  XF45        M>  M@  UR                  XE45        MT     U$ r   )r$   r7   )r?   r   r$   r'   r0   r)   r@   _drop_descrs          r   r    drop_fields.<locals>._drop_descr!  sl    DlG!}}(#G8OOTM2  0  r!   r   rp   rq   )r   setr#   rE   emptyshaper   rr   )r   r   rp   rq   r'   r   r   s         @r   r   r     sc    F z"" \
_
 4::z2HXXdjj1F"40Fv:FFr!   c                     U Vs/ s H  oDU R                   U   4PM     nn[        R                  " U R                  US9n[	        X5      n[        XbUS9$ s  snf )aL  
Return a new array keeping only the fields in `keep_names`,
and preserving the order of those fields.

Parameters
----------
base : array
    Input array
keep_names : string or sequence
    String or sequence of strings corresponding to the names of the
    fields to keep. Order of the names will be preserved.
usemask : {False, True}, optional
    Whether to return a masked array or not.
asrecarray : string or sequence, optional
    Whether to return a recarray or a mrecarray (`asrecarray=True`) or
    a plain ndarray or masked array with flexible dtype. The default
    is False.
r   r   )r#   rE   r   r   r   rr   )r   
keep_namesrp   rq   r   r'   r   s          r   _keep_fieldsr   7  sS    & -77JqDJJqM"JH7XXdjj1F"40Fv:FF 8s   Ac                     U 4$ r   r   r   r   s     r   _rec_drop_fields_dispatcherr   P  r   r!   c                     [        XSSS9$ )zC
Returns a new numpy.recarray with fields in `drop_names` dropped.
FTr   )r   r   s     r   r   r   T  s    
 t4HHr!   c                     U 4$ r   r   )r   
namemappers     r   _rename_fields_dispatcherr   \  r   r!   c                 X   ^ U4S jmT" U R                   U5      nU R                  U5      $ )a  
Rename the fields from a flexible-datatype ndarray or recarray.

Nested fields are supported.

Parameters
----------
base : ndarray
    Input array whose fields must be modified.
namemapper : dictionary
    Dictionary mapping old field names to their new version.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
...   dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])])
>>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'})
array([(1, (2., [ 3., 30.])), (4, (5., [ 6., 60.]))],
      dtype=[('A', '<i8'), ('b', [('ba', '<f8'), ('BB', '<f8', (2,))])])

c                    > / nU R                    HR  nUR                  X35      nX   nUR                   b  UR                  UT" XQ5      45        M@  UR                  XE45        MT     U$ r   )r$   rP   r7   )r?   r   r'   r0   newnamer)   _recursive_rename_fieldss         r   r   /rename_fields.<locals>._recursive_rename_fieldsy  sg    LLD nnT0GlG}}(6wKL  23 ! r!   )r#   rk   )r   r   r'   r   s      @r   r   r   `  s)    2 (

J?H99Xr!   c              #   ,   #    U v   U S h  vN   g  N7fr   r   )r   r$   rt   dtypesrd   rp   rq   s          r   _append_fields_dispatcherr     s     
JOO   
c                 Z   [        U[        [        45      (       a&  [        U5      [        U5      :w  a  Sn[	        U5      eO[        U[
        5      (       a  U/nU/nUca  U Vs/ s H  n[        R                  " USSS9PM     nn[        X5       V	Vs/ s H"  u  pUR                  XR                  4/5      PM$     nn	nO[        U[        [        45      (       d  U/n[        U5      [        U5      :w  a+  [        U5      S:X  a  U[        U5      -  nOSn[	        U5      e[        X!U5       VV
Vs/ s H.  u  pn[        R                  " USSUS9R                  X4/5      PM0     nn
nn[        XUS9n [        U5      S:  a  [        USUUS	9nOUR                  5       n[        R                  " [        [        U 5      [        U5      5      [!        U R                  5      [!        UR                  5      -   S
9n[#        X5      n[#        X,5      n[%        XUS9$ s  snf s  snn	f s  snn
nf )a  
Add new fields to an existing array.

The names of the fields are given with the `names` arguments,
the corresponding values with the `data` arguments.
If a single field is appended, `names`, `data` and `dtypes` do not have
to be lists but just values.

Parameters
----------
base : array
    Input array to extend.
names : string, sequence
    String or sequence of strings corresponding to the names
    of the new fields.
data : array or sequence of arrays
    Array or sequence of arrays storing the fields to add to the base.
dtypes : sequence of datatypes, optional
    Datatype or sequence of datatypes.
    If None, the datatypes are estimated from the `data`.
fill_value : {float}, optional
    Filling value used to pad missing data on the shorter arrays.
usemask : {False, True}, optional
    Whether to return a masked array or not.
asrecarray : {False, True}, optional
    Whether to return a recarray (MaskedRecords) or not.

z7The number of arrays does not match the number of namesNT)copysubokrD   z5The dtypes argument must be None, a dtype, or a list.)r   r   r#   )rp   rd   )rG   rp   rd   r   r   )rU   r8   rO   r&   r%   r^   rE   r   r   rk   r#   r   popri   
masked_allr   r5   r   rr   )r   r$   rt   r   rd   rp   rq   msgrH   r0   r   dr   s                r   r   r     s   @ %%''u:T"KCS/! # 
E3			x~<@ADqT2DA;>u;KL;Kitww();KL&5$-00ZFt9F#6{a#d)+M o%!$T&!9;!9IQ1 T;@@1&J!9 	 ; *ED
4y1}D$'13 xxz]]CIs4y!TZZ(>$**+EEGF #40F"40Fv:FF7 BL;s   $ H)H 25H&c              #   ,   #    U v   U S h  vN   g  N7fr   r   r   r$   rt   r   s       r   _rec_append_fields_dispatcherr     s     
JOOr   c           	          [        XX#SSS9$ )a  
Add new fields to an existing array.

The names of the fields are given with the `names` arguments,
the corresponding values with the `data` arguments.
If a single field is appended, `names`, `data` and `dtypes` do not have
to be lists but just values.

Parameters
----------
base : array
    Input array to extend.
names : string, sequence
    String or sequence of strings corresponding to the names
    of the new fields.
data : array or sequence of arrays
    Array or sequence of arrays storing the fields to add to the base.
dtypes : sequence of datatypes, optional
    Datatype or sequence of datatypes.
    If None, the datatypes are estimated from the `data`.

See Also
--------
append_fields

Returns
-------
appended_array : np.recarray
TF)rt   r   rq   rp   )r   r   s       r   r   r     s    > 4$(%9 9r!   c                     U 4$ r   r   )rH   alignrecurses      r   _repack_fields_dispatcherr     s	    4Kr!   c                    [        U [        R                  5      (       d$  [        U R                  XS9nU R	                  USS9$ U R
                  c  U $ / nU R
                   HU  nU R                  U   nU(       a  [        US   USS9nOUS   n[        U5      S:X  a  US   U4nUR                  XW45        MW     [        R                  " XAS9n[        R                  " U R                  U45      $ )	ac  
Re-pack the fields of a structured array or dtype in memory.

The memory layout of structured datatypes allows fields at arbitrary
byte offsets. This means the fields can be separated by padding bytes,
their offsets can be non-monotonically increasing, and they can overlap.

This method removes any overlaps and reorders the fields in memory so they
have increasing byte offsets, and adds or removes padding bytes depending
on the `align` option, which behaves like the `align` option to
`numpy.dtype`.

If `align=False`, this method produces a "packed" memory layout in which
each field starts at the byte the previous field ended, and any padding
bytes are removed.

If `align=True`, this methods produces an "aligned" memory layout in which
each field's offset is a multiple of its alignment, and the total itemsize
is a multiple of the largest alignment, by adding padding bytes as needed.

Parameters
----------
a : ndarray or dtype
   array or dtype for which to repack the fields.
align : boolean
   If true, use an "aligned" memory layout, otherwise use a "packed" layout.
recurse : boolean
   If True, also repack nested structures.

Returns
-------
repacked : ndarray or dtype
   Copy of `a` with fields repacked, or `a` itself if no repacking was
   needed.

Examples
--------
>>> import numpy as np

>>> from numpy.lib import recfunctions as rfn
>>> def print_offsets(d):
...     print("offsets:", [d.fields[name][1] for name in d.names])
...     print("itemsize:", d.itemsize)
...
>>> dt = np.dtype('u1, <i8, <f8', align=True)
>>> dt
dtype({'names': ['f0', 'f1', 'f2'], 'formats': ['u1', '<i8', '<f8'], 'offsets': [0, 8, 16], 'itemsize': 24}, align=True)
>>> print_offsets(dt)
offsets: [0, 8, 16]
itemsize: 24
>>> packed_dt = rfn.repack_fields(dt)
>>> packed_dt
dtype([('f0', 'u1'), ('f1', '<i8'), ('f2', '<f8')])
>>> print_offsets(packed_dt)
offsets: [0, 1, 9]
itemsize: 17

)r   r   F)r   r   T   r3   r   )
rU   rE   r#   r   astyper$   r-   r&   r7   r~   )rH   r   r   dt	fieldinfor0   rf   fmts           r   r   r     s    z a""177%Axxx''wwIhhtnAeTBCa&Cs8q=FD>D$%  
)	)B88QVVRL!!r!   c                    S n/ nU R                    H  nU R                  U   nUS   US   pvU" U5      u  phUR                   c.  UR                  [        R                  " Xh445      XU-   45        M`  [        XgU-   5      n	UR                  n
[        U5       HK  nUS:X  a  UR                  U	5        M  UR                  U	 VVVs/ s H  u  poXX-  -   4PM     snnn5        MM     M     U$ s  snnnf )z
Returns a flat list of (dtype, count, offset) tuples of all the
scalar fields in the dtype "dt", including nested fields, in left
to right order.
c                     SnU R                   S:w  a5  U R                    H  nX-  nM	     U R                  n U R                   S:w  a  M5  X4$ )NrD   r   )r   r   )r   r   r   s      r   
count_elem+_get_fields_and_offsets.<locals>.count_elem_  sG    hh"n !B hh"n yr!   r   rD   )	r$   r-   r7   rE   r#   _get_fields_and_offsetsitemsizeranger=   )r   offsetr   r-   r0   r(   f_dtf_offsetr   	subfieldsr   ir   cos                  r   r   r   V  s     F		$q58hT"::MM288T4L116GHI/6GHI==D1X6MM),MMY"OY'!qaf*#5Y"OP  " M #Ps   C,c                 L   [        U 5      S::  a  U$ U S   U S   :  nU(       a  [        [        U 5      [        U5      5      nO[        X5      nSnSnU HB  u  pxUS:w  a   U(       a    gUc  UnXb:w  a    gXxS-
  U-  -   n	OUn	Ub  Xu-
  n
Uc  U
nXj:w  a    gU	nMD     U(       a  U* $ U$ )z
Returns the stride between the fields, or None if the stride is not
constant. The values in "counts" designate the lengths of
subarrays. Subarrays are treated as many contiguous fields, with
always positive stride.
rD   r   N)r&   r   reversed)offsetscountsr   negativeitprev_offsetstrider   r   
end_offset
new_strides              r   _common_strider   {  s     7|qqzGAJ&H'"HV$45!KFA:~!!19"88JJ"-J~## ' * wMr!   c                     U 4$ r   r   )arrr#   r   castings       r   &_structured_to_unstructured_dispatcherr     	    6Mr!   c                 <  ^ U R                   R                  c  [        S5      e[        U R                   5      n[	        U5      nUS:X  a  Uc  [        S5      eUS:X  a  [        S5      e[        U6 u  pgn[        U5       V	s/ s H  n	SR                  U	5      PM     n
n	Uc.  [        R                  " U Vs/ s H  oR                  PM     sn6 mO[        R                   " U5      m[        R                   " U
UUU R                   R                  S.5      nU R                  U5      n [        U 5      [        R                  [        R                   [        R"                  4;   nU(       GdD  U(       Ga<  [%        U4S jU 5       5      (       Ga!  ['        XTR                  5      nUGb  U R(                  nU R*                  [-        U5      TR                  4-   nU R.                  [1        U5      S	4-   nU S
[        R2                  4   R                  [        R4                  5      n U S
[7        U5      S24   n [        R8                  R:                  R=                  U UUSS9n U R                  T5      S   n US:  a
  U S
SSS24   n [        U 5      [        UR>                  5      La  U" U 5      n U $ [        R                   " U
U Vs/ s H  nTUR*                  4PM     snS.5      nU RA                  UX#S9n U R                  T[-        U5      445      $ s  sn	f s  snf s  snf )a  
Converts an n-D structured array into an (n+1)-D unstructured array.

The new array will have a new last dimension equal in size to the
number of field-elements of the input array. If not supplied, the output
datatype is determined from the numpy type promotion rules applied to all
the field datatypes.

Nested fields, as well as each element of any subarray fields, all count
as a single field-elements.

Parameters
----------
arr : ndarray
   Structured array or dtype to convert. Cannot contain object datatype.
dtype : dtype, optional
   The dtype of the output unstructured array.
copy : bool, optional
    If true, always return a copy. If false, a view is returned if
    possible, such as when the `dtype` and strides of the fields are
    suitable and the array subtype is one of `numpy.ndarray`,
    `numpy.recarray` or `numpy.memmap`.

    .. versionchanged:: 1.25.0
        A view can now be returned if the fields are separated by a
        uniform stride.

casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
    See casting argument of `numpy.ndarray.astype`. Controls what kind of
    data casting may occur.

Returns
-------
unstructured : ndarray
   Unstructured array with one more dimension.

Examples
--------
>>> import numpy as np

>>> from numpy.lib import recfunctions as rfn
>>> a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)])
>>> a
array([(0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]),
       (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.])],
      dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])
>>> rfn.structured_to_unstructured(a)
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])

>>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)],
...              dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')])
>>> np.mean(rfn.structured_to_unstructured(b[['x', 'z']]), axis=-1)
array([ 3. ,  5.5,  9. , 11. ])

Narr must be a structured arrayr   z(arr has no fields. Unable to guess dtypez#arr with no fields is not supportedf{}r$   formatsr   r   c              3   @   >#    U  H  oR                   T:H  v   M     g 7fr   )r   )r/   r   	out_dtypes     r   r1   -structured_to_unstructured.<locals>.<genexpr>	  s     &Jcww)';cs   rD   .T)r   .r   r$   r   r   r   )!r#   r$   r%   r   r&   NotImplementedErrorr   r   formatrE   result_typer   r   rk   r~   r   ro   memmapallr   __array_wrap__r   sumstridesabsnewaxisuint8minlibstride_tricks
as_strided__self__r   )r   r#   r   r   r-   n_fieldsdtsr   r   r   r$   r   flattened_fieldscan_viewcommon_stridewrap	new_shapenew_stridespacked_fieldsr   s                      @r   r   r     s   x yy9::$SYY/F6{H1}CDD	Q!"GHH<C&+Ho6oU\\!_oE6}NNs$;sWWs$;<	HHUO	 xx%,/,3-0YY-?-?!A B ((#
$C
 CyRZZbii@@Hh3&Jc&J#J#J 'w	8J8JK$%%D		S[)2D2D$EEI++]);Q(??Kc2::o&++BHH5Cc3w<=()C&&&&11#2;2=8< 2 >C ((9%f-Cq #tt)nCyT]] 33 3iJ HHuJM)N#B9bhh*?#)NP QM
**]*
?C 88YV/00q 7 %<b *Os   L5LL
c                     U 4$ r   r   )r   r#   r$   r   r   r   s         r   &_unstructured_to_structured_dispatcherr  /  r   r!   c                 l   U R                   S:X  a  [        S5      eU R                   S   nUS:X  a  [        S5      eUcu  Uc*  [        U5       Vs/ s H  nSR	                  U5      PM     nn[
        R                  " U Vs/ s H  owU R                  4PM     snUS9n[        U5      n	[        U	6 u  pnOUb  [        S5      e[
        R                  " U5      n[        U5      n	[        U	5      S:X  a  / / / pn
O[        U	6 u  pnU[        U5      :w  a  [        S	5      eUnU(       a  UR                  (       d  [        S
5      e[        [        U	5      5       Vs/ s H  nSR	                  U5      PM     nn[
        R                  " UU
 Vs/ s H  oR                  UR                   4PM     snS.5      n[
        R                  " U 5      R                  U5      n [
        R                  " UU
UUR                  S.5      nU R                  XUS9n U R                  U5      S   $ s  snf s  snf s  snf s  snf )ar  
Converts an n-D unstructured array into an (n-1)-D structured array.

The last dimension of the input array is converted into a structure, with
number of field-elements equal to the size of the last dimension of the
input array. By default all output fields have the input array's dtype, but
an output structured dtype with an equal number of fields-elements can be
supplied instead.

Nested fields, as well as each element of any subarray fields, all count
towards the number of field-elements.

Parameters
----------
arr : ndarray
   Unstructured array or dtype to convert.
dtype : dtype, optional
   The structured dtype of the output array
names : list of strings, optional
   If dtype is not supplied, this specifies the field names for the output
   dtype, in order. The field dtypes will be the same as the input array.
align : boolean, optional
   Whether to create an aligned memory layout.
copy : bool, optional
    See copy argument to `numpy.ndarray.astype`. If true, always return a
    copy. If false, and `dtype` requirements are satisfied, a view is
    returned.
casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
    See casting argument of `numpy.ndarray.astype`. Controls what kind of
    data casting may occur.

Returns
-------
structured : ndarray
   Structured array with fewer dimensions.

Examples
--------
>>> import numpy as np

>>> from numpy.lib import recfunctions as rfn
>>> dt = np.dtype([('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)])
>>> a = np.arange(20).reshape((4,5))
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
>>> rfn.unstructured_to_structured(a, dt)
array([( 0, ( 1.,  2), [ 3.,  4.]), ( 5, ( 6.,  7), [ 8.,  9.]),
       (10, (11., 12), [13., 14.]), (15, (16., 17), [18., 19.])],
      dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])

r   z$arr must have at least one dimensionr   r   z&last axis with size 0 is not supportedr   r   z!don't supply both dtype and nameszVThe length of the last dimension of arr must be equal to the number of fields in dtypez'align was True but dtype is not alignedr   r   r   r   )r   r%   r   r   r   rE   r#   r   r   r&   r  isalignedstructascontiguousarrayrk   r   r   )r   r#   r$   r   r   r   n_elemr   r   r-   r  r   r   r   r  r  s                   r   r   r   3  s   r yyB?@@YYr]F{!"JKK}=.3Fm<mU\\!_mE<HHe<e#))ne<EJ	(3"F|W@AA(/v;!#%r2C#&< CS[  I J J	22FGG&+CK&89&8U\\!_&8E9
 HHuJM)N#B99bhh*?#)NP QM


s
#
(
(
7C xx%,/,3-6-?-?!A B **%'*
BC 88Iv&&Q =<, : *Os   H" H'H,
!H1
c                     U4$ r   r   )funcr   s     r   _apply_along_fields_dispatcherr    s	    6Mr!   c                 j    UR                   R                  c  [        S5      e[        U5      nU " USS9$ )a   
Apply function 'func' as a reduction across fields of a structured array.

This is similar to `numpy.apply_along_axis`, but treats the fields of a
structured array as an extra axis. The fields are all first cast to a
common type following the type-promotion rules from `numpy.result_type`
applied to the field's dtypes.

Parameters
----------
func : function
   Function to apply on the "field" dimension. This function must
   support an `axis` argument, like `numpy.mean`, `numpy.sum`, etc.
arr : ndarray
   Structured array for which to apply func.

Returns
-------
out : ndarray
   Result of the reduction operation

Examples
--------
>>> import numpy as np

>>> from numpy.lib import recfunctions as rfn
>>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)],
...              dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')])
>>> rfn.apply_along_fields(np.mean, b)
array([ 2.66666667,  5.33333333,  8.66666667, 11.        ])
>>> rfn.apply_along_fields(np.mean, b[['x', 'z']])
array([ 3. ,  5.5,  9. , 11. ])

r   r   )axis)r#   r$   r%   r   )r  r   uarrs      r   r   r     s6    H yy9::%c*D2r!   c                     X4$ r   r   )dstsrczero_unassigneds      r   !_assign_fields_by_name_dispatcherr&    s	    8Or!   c                     U R                   R                  c  XS'   gU R                   R                   H<  nX1R                   R                  ;  a  U(       a  SX'   M)  M+  [        X   X   U5        M>     g)az  
Assigns values from one structured array to another by field name.

Normally in numpy >= 1.14, assignment of one structured array to another
copies fields "by position", meaning that the first field from the src is
copied to the first field of the dst, and so on, regardless of field name.

This function instead copies "by field name", such that fields in the dst
are assigned from the identically named field in the src. This applies
recursively for nested structures. This is how structure assignment worked
in numpy >= 1.6 to <= 1.13.

Parameters
----------
dst : ndarray
src : ndarray
    The source and destination arrays during assignment.
zero_unassigned : bool, optional
    If True, fields in the dst for which there was no matching
    field in the src are filled with the value 0 (zero). This
    was the behavior of numpy <= 1.13. If False, those fields
    are not modified.
N.r   )r#   r$   r   )r#  r$  r%  r0   s       r   r   r     s`    4 yyC		yy&	  "#)SY"13  r!   c                     U 4$ r   r   )r   required_dtypes     r   _require_fields_dispatcherr*    s	    8Or!   c                 Z    [         R                  " U R                  US9n[        X 5        U$ )a  
Casts a structured array to a new dtype using assignment by field-name.

This function assigns from the old to the new array by name, so the
value of a field in the output array is the value of the field with the
same name in the source array. This has the effect of creating a new
ndarray containing only the fields "required" by the required_dtype.

If a field name in the required_dtype does not exist in the
input array, that field is created and set to 0 in the output array.

Parameters
----------
a : ndarray
   array to cast
required_dtype : dtype
   datatype for output array

Returns
-------
out : ndarray
    array with the new dtype, with field values copied from the fields in
    the input array with the same name

Examples
--------
>>> import numpy as np

>>> from numpy.lib import recfunctions as rfn
>>> a = np.ones(4, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')])
>>> rfn.require_fields(a, [('b', 'f4'), ('c', 'u1')])
array([(1., 1), (1., 1), (1., 1), (1., 1)],
  dtype=[('b', '<f4'), ('c', 'u1')])
>>> rfn.require_fields(a, [('b', 'f4'), ('newf', 'u1')])
array([(1., 0), (1., 0), (1., 0), (1., 0)],
  dtype=[('b', '<f4'), ('newf', 'u1')])

r   )rE   r   r   r   )r   r)  outs      r   r   r     s&    P ((5;;n
5C#%Jr!   c                     U $ r   r   )arraysrw   rp   rq   autoconverts        r   _stack_arrays_dispatcherr0  '  s    Mr!   c           	      @   [        U [        R                  5      (       a  U $ [        U 5      S:X  a  U S   $ U  Vs/ s H'  n[        R                  " U5      R                  5       PM)     nnU Vs/ s H  n[        U5      PM     nnU Vs/ s H  oUR                  PM     nnU V	s/ s H  oR                  PM     n
n	US   n[        U5      nU VV	s/ s H  u  pUPM	     nnn	USS  H  n[        U5       H  u  nnUU;  a&  UR                  UU45        UR                  U5        M2  UR                  U5      nUU   u  nnU(       a  U[        UU5      4UU'   Me  UU:w  d  Mm  [        SU< SU< S35      e   M     [        U5      S:X  a  [        R                  " U5      nO[        R                  " [        R                   " U5      4U5      n[        R"                  " [        R$                  SU4   5      n/ n['        XjUSS USS 5       Hc  u  p]nnUR                  R                  nUc  UUS[        U5      -     UU& M6  U H'  nUU   UU   UU& UU;  d  M  UR                  U5        M)     Me     [)        [+        UU5      X#S	9$ s  snf s  snf s  snf s  sn	f s  sn	nf )
a  
Superposes arrays fields by fields

Parameters
----------
arrays : array or sequence
    Sequence of input arrays.
defaults : dictionary, optional
    Dictionary mapping field names to the corresponding default values.
usemask : {True, False}, optional
    Whether to return a MaskedArray (or MaskedRecords is
    `asrecarray==True`) or a ndarray.
asrecarray : {False, True}, optional
    Whether to return a recarray (or MaskedRecords if `usemask==True`)
    or just a flexible-type ndarray.
autoconvert : {False, True}, optional
    Whether automatically cast the type of the field to the maximum.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> x = np.array([1, 2,])
>>> rfn.stack_arrays(x) is x
True
>>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)])
>>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
...   dtype=[('A', '|S3'), ('B', np.double), ('C', np.double)])
>>> test = rfn.stack_arrays((z,zz))
>>> test
masked_array(data=[(b'A', 1.0, --), (b'B', 2.0, --), (b'a', 10.0, 100.0),
                   (b'b', 20.0, 200.0), (b'c', 30.0, 300.0)],
             mask=[(False, False,  True), (False, False,  True),
                   (False, False, False), (False, False, False),
                   (False, False, False)],
       fill_value=(b'N/A', 1e+20, 1e+20),
            dtype=[('A', 'S3'), ('B', '<f8'), ('C', '<f8')])

rD   r   NzIncompatible type 'z' <> ''r   zf%ir   )rU   rE   r   r&   r   r   r#   r$   r5   r7   indexr   	TypeErrorri   concatenater   r  cumsumr_r   rr   rz   )r.  rw   rp   rq   r/  rH   rF   nrecordsr?   r   fldnamesdtype_lnewdescrr   r$   dtype_nfnamefdtypenameidxrB   cdtyper   r   seenr   jr0   s                              r   r   r   ,  sl   T &"**%%	V	ay39:6aq!'')6I: )*	1A	H*()y!ggyF)!'(AH(QiGg&H#$841Q8E$!":+G4ME6E!0U#++e,$W-	6).FF0C(DHW%v%#%+V%5 6 6 5  8}	* x 02H=255H-.	VCR[&*MLQ1aGGMME}12us4y()!A.D()$F4L1%4'D)  N }VX6&? ?O ;*)( %s   .J.J	J$JJc                     U 4$ r   r   )rH   key
ignoremaskreturn_indexs       r   _find_duplicates_dispatcherrG    s	    4Kr!   c                    [         R                  " U 5      R                  5       n [        U R                  5      nU nU(       a  XA    H  nXV   nM	     XQ   nUR                  5       nXW   nUR                  5       n	U	SS U	SS :H  n
U(       a  UR                  nSXSS '   [         R                  " S/U
45      n
U
SS U
SS -   U
SS& X   U
   nU(       a  XU
   4$ U$ )a  
Find the duplicates in a structured array along a given key

Parameters
----------
a : array-like
    Input array
key : {string, None}, optional
    Name of the fields along which to check the duplicates.
    If None, the search is performed by records
ignoremask : {True, False}, optional
    Whether masked data should be discarded or considered as duplicates.
return_index : {False, True}, optional
    Whether to return the indices of the duplicated values.

Examples
--------
>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> ndtype = [('a', int)]
>>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3],
...         mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype)
>>> rfn.find_duplicates(a, ignoremask=True, return_index=True)
(masked_array(data=[(1,), (1,), (2,), (2,)],
             mask=[(False,), (False,), (False,), (False,)],
       fill_value=(999999,),
            dtype=[('a', '<i8')]), array([0, 1, 3, 4]))
Nr   rD   F)	rE   r   r   r   r#   argsortrn   
recordmaskr5  )rH   rD  rE  rF  r-   r   r4   sortidx
sortedbase
sorteddataflag
sortedmask
duplicatess                r   r	   r	     s    < 	a A(FD
A7D yllnGJ""$JsOz!"~-D**
$^>>E7D/*DSb	DH$D"ID!JDM**r!   c	                     X4$ r   r   )	rD  r1r2jointype	r1postfix	r2postfixrw   rp   rq   s	            r   _join_by_dispatcherrW         8Or!   c	                 	  ^  US;  a  [        SU-  5      e[        T [        5      (       a  T 4m [        [	        T 5      5      [        T 5      :w  a,  [        U 4S j[        T 5       5       5      n	[        SU	-  5      eT  HQ  n
XR                  R                  ;  a  [        SU
-  5      eXR                  R                  ;  d  ME  [        SU
-  5      e   UR                  5       nUR                  5       n[        U5      nUR                  R                  UR                  R                  p[	        U5      [	        U5      -  [	        T 5      -
  nU(       a   U(       d  U(       d  SnUS-  n[        U5      eU Vs/ s H  nUT ;   d  M  UPM     nn[        UU5      n[        UU5      n[        R                  " UU45      nUR                  T S	9nUU   n[        R                  " S
/USS USS :H  45      nUSS USS -   USS& UU   nUUU:     nUUU:     U-
  n[        U5      [        U5      nnUS:X  a  Su  nnOUS:X  ab  UU)    n[        R                  " UUUU:     45      n[        R                  " UUUU:     U-
  45      n[        U5      U-
  [        U5      U-
  nnO:US:X  a4  UU)    n[        R                  " UUUU:     45      n[        U5      U-
  SnnUU   UU   n n[        UR                  5      n![        UR                  5       H!  u  n"n#U"T ;  d  M  U!R!                  U"U#45        M#     [        UR                  5       H_  u  n"n#[#        S U! 5       5      n$ U$R%                  U"5      n%U!U%   u  n&n'U"T ;   a  U"['        U#U'5      4U!U%'   MK  U"U-   U'4U"U-   U#4/U!U%U%S-   & Ma     [        R                  " U!5      n!['        UU5      n([        R(                  " U(W-   W-   4U!S9n)U)R                  R                  n$U HF  n*UU*   n+U*U$;  d  U*U;   a  U(       d  U*T ;  a  U*U-  n*U)U*   n,U+SU U,SU& US;   d  M;  U+US U,U(U(U-   & MH     U HM  n*U U*   n+U*U$;  d  U*U;   a  U(       d  U*T ;  a  U*U-  n*U)U*   n,U+SU U,SU& US:X  d  M;  U(       d  MD  U+US U,U* S& MO     U)R+                  T S	9  [-        XxS9n-[/        [1        U)U5      40 U-D6$ s  snf ! [          a    U!R!                  U"U#45         GM  f = f)a  
Join arrays `r1` and `r2` on key `key`.

The key should be either a string or a sequence of string corresponding
to the fields used to join the array.  An exception is raised if the
`key` field cannot be found in the two input arrays.  Neither `r1` nor
`r2` should have any duplicates along `key`: the presence of duplicates
will make the output quite unreliable. Note that duplicates are not
looked for by the algorithm.

Parameters
----------
key : {string, sequence}
    A string or a sequence of strings corresponding to the fields used
    for comparison.
r1, r2 : arrays
    Structured arrays.
jointype : {'inner', 'outer', 'leftouter'}, optional
    If 'inner', returns the elements common to both r1 and r2.
    If 'outer', returns the common elements as well as the elements of
    r1 not in r2 and the elements of not in r2.
    If 'leftouter', returns the common elements and the elements of r1
    not in r2.
r1postfix : string, optional
    String appended to the names of the fields of r1 that are present
    in r2 but absent of the key.
r2postfix : string, optional
    String appended to the names of the fields of r2 that are present
    in r1 but absent of the key.
defaults : {dictionary}, optional
    Dictionary mapping field names to the corresponding default values.
usemask : {True, False}, optional
    Whether to return a MaskedArray (or MaskedRecords is
    `asrecarray==True`) or a ndarray.
asrecarray : {False, True}, optional
    Whether to return a recarray (or MaskedRecords if `usemask==True`)
    or just a flexible-type ndarray.

Notes
-----
* The output is sorted along the key.
* A temporary array is formed by dropping the fields not in the key for
  the two arrays and concatenating the result. This array is then
  sorted, and the common entries selected. The output is constructed by
  filling the fields with the selected entries. Matching is not
  preserved if there are some duplicates...

)innerouter	leftouterzWThe 'jointype' argument should be in 'inner', 'outer' or 'leftouter' (got '%s' instead)c              3   H   >#    U  H  u  pUTUS -   S ;   d  M  Uv   M     g7f)rD   Nr   )r/   r   xrD  s      r   r1   join_by.<locals>.<genexpr>
  s%     A!s1Q34y.11s   "	"zduplicate join key %rzr1 does not have key field %rzr2 does not have key field %rz8r1 and r2 contain common names, r1postfix and r2postfix zcan't both be empty)orderFrD   Nr   rZ  )r   r   r[  r\  r   c              3   *   #    U  H	  u  pUv   M     g 7fr   r   r.   s      r   r1   r_  N  s     4VkdTVs   r   )r[  r\  r   )r%   rU   r^   r&   r   next	enumerater#   r$   r   r   ri   r5  rI  rE   r5   r7   rO   r3  r   r   sortdictrr   rz   ).rD  rR  rS  rT  rU  rV  rw   rp   rq   dupr0   nb1r1namesr2names
collisionsr   r   key1r1kr2kauxidx_sortflag_inidx_inidx_1idx_2r1cmnr2cmnr1spcr2spcidx_outs1s2r?   r=  r>  r$   r?  rB   r@  cmnr   r4   selectedr)   kwargss.   `                                             r   r   r     sF   h 66<>FG 	
 #sf 3s8}C A	#AA03677xx~~%<tCDDxx~~%<tCDD	  
B	B b'C((.."((..g g,W-S9J9	H$$o  -118QD-
r4
 C
r4
 C ..#s
$C{{{%H
h-C nnugs12w#cr(':;<G12;"-GCRLgFFSL"EFcM#c)E%j#e*EU7	W	G8$w#'?@Aw3'@3'FGHe*u,c%j5.@	[	 G8$w#'?@Ae*u,a5	2e9R CII&F (1vMM5&/* 2
 (1v 4V44	kk%(G wIAv|#(#ff*=">w
 Y&/Y&//ww{+% 2. XXfF eU
C]]C%K%/1@FLLEa5E>a7l9#NA)"6E*--'/'7GCe$  a5E>a7l9#NA)"6E*UU'/GUFG  KKcK'9F}VX6A&AAs .\  	+MM5&/**	+s   6
SS#SS54S5c                     X4$ r   r   )rD  rR  rS  rT  rU  rV  rw   s          r   _rec_join_dispatcherr    rX  r!   c           	      6    [        X4UUSSS9n[        XU40 UD6$ )z
Join arrays `r1` and `r2` on keys.
Alternative to join_by, that always returns a np.recarray.

See Also
--------
join_by : equivalent function
FT)rT  rU  rV  rw   rp   rq   )re  r   )rD  rR  rS  rT  rU  rV  rw   r}  s           r   r   r     s,     8I#UtEF3B)&))r!   )F)NN)NT)TFr   )NNNN)r   FFF)Nr   TF)FF)r   )NNN)NFunsafe)NNNNN)NNFFr  )T)NTFF)NTF)NNNNNN)rZ  12NTF)rZ  r  r  N)?__doc__rb   numpyrE   numpy.mari   numpy.ma.mrecordsmrecordsrl   numpy._core.overridesr   numpy.lib._iotoolsr   __all__r    r   r5   r   r   r
   rI   rL   r   rW   r_   rg   rr   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r  r   r&  r   r*  r   r0  r   rG  r	   rW  r   r  r   r   r!   r   <module>r     s          9 . :;$ <$N
@BB6 8-`
 "0" BF6:
 1238+0E 3EP 01:G 2:GzG2 45I 6I 23% 4%P 9=HL 23,0:?CG 4CGL
 679 89D 23Q" 4Q"f#J*Z BF37 ?@1 A1D CGJN ?@BG3;i' Ai'V 78' 9'V :;#3 <#3J 34) 5)X =A:>
 12AF"U? 3U?r 48
 457 67v ?C04 ,-DG49pB .pBh ?C -.EH* /* r!   