B
    q\                 @   s   d Z ddlmZ ddlZddlmZmZ ddlmZ ddlZ	ddl
mZ ddlmZ dgZG d	d deZdddZdd Zdd Zdd Zdd Zdd ZdS )z
High-level operations for numpy structured arrays.

Some code and inspiration taken from numpy.lib.recfunctions.join_by().
Redistribution license restrictions apply.
    )chainN)OrderedDictCounter)Sequence   )	_np_utilsTableMergeErrorc               @   s   e Zd ZdS )r   N)__name__
__module____qualname__ r   r   5lib/python3.7/site-packages/astropy/table/np_utils.pyr      s   {col_name}_{table_name}c                s  t  fddg }|dkr4dd tt D }xt D ]\}}|| }x||jjD ]p}|kr||kr| n@t }	|		| t
fdd|	D r|j|d}|| | |< qXW q>W t|}
d	d |
 D }|rtd
|tfdd|D S )a  
    Find the column names mapping when merging the list of structured ndarrays
    ``arrays``.  It is assumed that col names in ``common_names`` are to be
    merged into a single column while the rest will be uniquely represented
    in the output.  The args ``uniq_col_name`` and ``table_names`` specify
    how to rename columns in case of conflicts.

    Returns a dict mapping each output column name to the input(s).  This takes the form
    {outname : (col_name_0, col_name_1, ...), ... }.  For key columns all of input names
    will be present, while for the other non-key columns the value will be (col_name_0,
    None, ..) or (None, col_name_1, ..) etc.
    c                  s   d gt   S )N)lenr   )arraysr   r   <lambda>(   s    z"get_col_name_map.<locals>.<lambda>Nc             S   s   g | ]}t |d  qS )r   )str).0Ziir   r   r   
<listcomp>,   s    z$get_col_name_map.<locals>.<listcomp>c             3   s   | ]} |j jkV  qd S )N)dtypenames)r   other)namer   r   	<genexpr>=   s    z#get_col_name_map.<locals>.<genexpr>)
table_nameZcol_namec             S   s   g | ]\}}|d kr|qS )r   r   )r   r   countr   r   r   r   E   s    zhMerging column names resulted in duplicates: {0}.  Change uniq_col_name or table_names args to fix this.c             3   s   | ]}| | fV  qd S )Nr   )r   r   )col_name_mapr   r   r   L   s    )collectionsdefaultdictranger   	enumerater   r   appendlistpopanyformatr   itemsr   r   )r   Zcommon_namesZuniq_col_nameZtable_namesZcol_name_listidxarrayr   out_nameZothersZcol_name_countZrepeated_namesr   )r   r   r   r   get_col_name_map   s0    

r*   c             C   s   g }x|  D ]\}}dd t| |D }dd |D }yt|}W n8 tk
r| } ztd|d |jW dd}~X Y nX tdd |D }	t|	d	krtd
t|		 }
|
t|||
f qW |S )z
    Find the dtypes descrs resulting from merging the list of arrays' dtypes,
    using the column name mapping ``col_name_map``.

    Return a list of descrs for the output.
    c             S   s    g | ]\}}|d k	r|| qS )Nr   )r   arrr   r   r   r   r   ]   s    zget_descrs.<locals>.<listcomp>c             S   s   g | ]}|d k	r|qS )Nr   )r   r   r   r   r   r   `   s    z.The '{0}' columns have incompatible types: {1}r   Nc             s   s   | ]}|j d d V  qdS )r   N)shape)r   colr   r   r   r   l   s    zget_descrs.<locals>.<genexpr>r   z&Key columns {0!r} have different shape)r&   zipcommon_dtyper   r%   _incompat_typessetr   r   r#   r!   fix_column_name)r   r   Z
out_descrsr)   Zin_namesZin_colsr   r   tmeZuniq_shapesr,   r   r   r   
get_descrsQ   s    "r4   c                s   t jt jt jt jt jf t fdd| D }t|dkr`dd | D }td	|}||_
|dd | D }x&|D ]}|jjdkrtd	|j |d
< qtW t dd |D }|jjS )z
    Use numpy to find the common dtype for a list of structured ndarray columns.

    Only allow columns within the following fundamental numpy data types:
    np.bool_, np.object_, np.number, np.character, np.void
    c             3   s$   | ] t  fd dD V  qdS )c             3   s   | ]}t  jj|V  qd S )N)
issubclassr   type)r   Znp_type)r-   r   r   r   ~   s    z)common_dtype.<locals>.<genexpr>.<genexpr>N)tuple)r   )np_types)r-   r   r   ~   s   zcommon_dtype.<locals>.<genexpr>r   c             S   s   g | ]}|j jqS r   )r   r   )r   r-   r   r   r   r      s    z common_dtype.<locals>.<listcomp>z#Columns have incompatible types {0}c             S   s   g | ]}t jd |jdqS )r   )r   )npemptyr   )r   r-   r   r   r   r      s    )SU0r   c             S   s   g | ]}|d  qS )r   r   )r   r+   r   r   r   r      s    )r9   Zbool_Zobject_Znumber	characterZvoidr1   r   r   r%   r0   r   Zkinditemsizer(   r   )ZcolsZ
uniq_typesZincompat_typesr3   Zarrsr+   Z
arr_commonr   )r8   r   r/   v   s    

r/   c             C   s\   d}t | tst|x,| D ]$}t |tjr8|jjd krt|qW t| dkrXtdd S )Nz@`arrays` arg must be a sequence (e.g. list) of structured arraysr   z,`arrays` arg must include at least one array)	
isinstancer   	TypeErrorr9   Zndarrayr   r   r   
ValueError)r   errr(   r   r   r   (_check_for_sequence_of_structured_arrays   s    

rD   c             C   s0   | dk	r,yt | } W n tk
r*    Y nX | S )z
    Fixes column names so that they are compatible with Numpy on
    Python 2.  Raises a ValueError exception if the column name
    contains Unicode characters, which can not reasonably be used as a
    column name.
    N)r   UnicodeEncodeError)valr   r   r   r2      s    r2   c                sj   t | d }tj| td  fddt|D }g }x|D ] | jj q:W d|}tj	j
||dS )aT  
    Partial replacement for `~numpy.core.records.fromrecords` which includes
    a workaround for the bug with unicode arrays described at:
    https://github.com/astropy/astropy/issues/3052

    This should not serve as a full replacement for the original function;
    this only does enough to fulfill the needs of the table module.
    r   )r   c                s"   g | ]}t  d |f  qS ).)r9   r(   tolist)r   i)objr   r   r      s    z(recarray_fromrecords.<locals>.<listcomp>,)formats)r   r9   r(   objectr   r!   r   r   joinZrecZ
fromarrays)Zrec_listZnfieldsZ
array_listrK   r   )rI   r   recarray_fromrecords   s    

rN   )r   N)__doc__	itertoolsr   r   r   r   Zcollections.abcr   Znumpyr9   Znumpy.maZma r   __all__rB   r   r*   r4   r/   rD   r2   rN   r   r   r   r   <module>   s     
7%