
    ^i=Q                    b   d dl mZ d dlmZmZ d dlZd dlmZmZm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlmZ d dlZd dlmZmZ erd d	lmZ d d
lmZmZ d;dZe
	 	 	 	 d<d=d            Ze
	 	 	 	 d<d>d            Z	 	 	 	 d?d@d!ZdAd'ZdBd(Z	 dCdDd*Z dEd.Z! ed/          	 	 	 	 	 	 	 dFdGd:            Z"dS )H    )annotations)abcdefaultdictN)TYPE_CHECKINGAnyDefaultDictoverloadconvert_json_to_lines)
set_module)	is_scalar)	DataFrameSeries)Iterable)IgnoreRaiseScalarsstrreturnc                h    | d         dk    s| d         dk    r| S | dd         } t          |           S )zJ
    Helper function that converts JSON lists to line delimited JSON.
    r   []   r
   )r   s    D/usr/local/lib/python3.11/dist-packages/pandas/io/json/_normalize.pyconvert_to_line_delimitsr   '   s=     Q43;;1R5C<<	!B$A ###    .dsdictprefixseplevelint	max_level
int | Nonedict[str, Any]c                    d S N r   r    r!   r"   r$   s        r   nested_to_recordr+   4   s	     Sr   
list[dict]list[dict[str, Any]]c                    d S r(   r)   r*   s        r   r+   r+   >   s	     3r    .dict | list[dict]%dict[str, Any] | list[dict[str, Any]]c                H   d}t          | t                    r| g} d}g }| D ]}t          j        |          }|                                D ]\  }	}
t          |	t
                    st          |	          }	|dk    r|	}n||z   |	z   }t          |
t                    r|'||k    r!|dk    r|                    |	          }
|
||<   x|                    |	          }
|                    t          |
|||dz   |                     |	                    |           |r|d         S |S )a  
    A simplified json_normalize

    Converts a nested dict into a flat dict ("record"), unlike json_normalize,
    it does not attempt to extract a subset of the data.

    Parameters
    ----------
    ds : dict or list of dicts
    prefix: the prefix, optional, default: ""
    sep : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
    level: int, optional, default: 0
        The number of levels in the json string.

    max_level: int, optional, default: None
        The max depth to normalize.

    Returns
    -------
    d - dict or list of dicts, matching `ds`

    Examples
    --------
    >>> nested_to_record(
    ...     dict(flat1=1, dict1=dict(c=1, d=2), nested=dict(e=dict(c=1, d=2), d=2))
    ... )
    {'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}
    FTr   Nr   )

isinstancer   copydeepcopyitemsr   popupdater+   append)r   r    r!   r"   r$   	singletonnew_dsdnew_dkvnewkeys               r   r+   r+   H   sP   X I"d T	F  a  GGII 	Q 	QDAqa%% FFzz#) a&& %%9*<*<A::		!A$%E&M		!ALL)!VS%!)YOOPPPPe ayMr   datar   
key_stringnormalized_dict	separatorc                    t          | t                    rM|                                 D ]7\  }}| | | }|s|                    |          }t	          ||||           8n| ||<   |S )a3  
    Main recursive function
    Designed for the most basic use case of pd.json_normalize(data)
    intended as a performance improvement, see #15621

    Parameters
    ----------
    data : Any
        Type dependent on types contained within nested Json
    key_string : str
        New key (with separator(s) in) for data
    normalized_dict : dict
        The new normalized/flattened Json dict
    separator : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar
    rB   rC   rD   rE   )r4   r   r7   removeprefix_normalize_json)rB   rC   rD   rE   keyvaluenew_keys          r   rI   rI      s    . $ +**,, 	 	JC#5Y555G :!..y99" /#	    	 '+
#r   c                    d |                                  D             }t          d |                                  D             di |          }i ||S )aw  
    Order the top level keys and then recursively go to depth

    Parameters
    ----------
    data : dict or list of dicts
    separator : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

    Returns
    -------
    dict or list of dicts, matching `normalized_json_object`
    c                D    i | ]\  }}t          |t                    ||S r)   r4   r   .0r?   r@   s      r   
<dictcomp>z+_normalize_json_ordered.<locals>.<dictcomp>   s-    JJJ$!QjD6I6IJAJJJr   c                D    i | ]\  }}t          |t                    ||S r)   rO   rP   s      r   rR   z+_normalize_json_ordered.<locals>.<dictcomp>   s-    CCCtq!z!T/B/BCaCCCr   r/   rG   )r7   rI   )rB   rE   	top_dict_nested_dict_s       r   _normalize_json_orderedrV      sh     KJ$**,,JJJI"CCtzz||CCC	  L )i(<((r   dict | list[dict] | Anyc                    i }t          | t                    rt          |           }n%t          | t                    rfd| D             }|S |S )a  
    An optimized basic json_normalize

    Converts a nested dict into a flat dict ("record"), unlike
    json_normalize and nested_to_record it doesn't do anything clever.
    But for the most basic use cases it enhances performance.
    E.g. pd.json_normalize(data)

    Parameters
    ----------
    ds : dict or list of dicts
    sep : str, default '.'
        Nested records will generate names separated by sep,
        e.g., for sep='.', { 'foo' : { 'bar' : 0 } } -> foo.bar

    Returns
    -------
    frame : DataFrame
    d - dict or list of dicts, matching `normalized_json_object`

    Examples
    --------
    >>> _simple_json_normalize(
    ...     {
    ...         "flat1": 1,
    ...         "dict1": {"c": 1, "d": 2},
    ...         "nested": {"e": {"c": 1, "d": 2}, "d": 2},
    ...     }
    ... )
    {'flat1': 1, 'dict1.c': 1, 'dict1.d': 2, 'nested.e.c': 1, 'nested.e.d': 2, 'nested.d': 2}

    )rB   rE   c                2    g | ]}t          |           S )r!   )_simple_json_normalize)rQ   rowr!   s     r   
<listcomp>z*_simple_json_normalize.<locals>.<listcomp>  s'    SSS 6s D D DSSSr   )r4   r   rV   list)r   r!   normalized_json_objectnormalized_json_lists    `  r   r[   r[      sm    V  "d $!8bC!P!P!P	B		 $SSSSPRSSS##!!r   meta"str | list[str | list[str]] | NoneNonec                l   | dS t          | t                    rdS | D ]}t          |t                    rB|D ]>}t          |t                    s't          dt	          |          j         d|          ?Yt          |t                    s't          dt	          |          j         d|          dS )aD  
    Validate that meta parameter contains only strings or lists of strings.
    Parameters
    ----------
    meta : str or list of str or list of list of str or None
        The meta parameter to validate.
    Raises
    ------
    TypeError
        If meta contains elements that are not strings or lists of strings.
    Nz9All elements in nested meta paths must be strings. Found z: zBAll elements in 'meta' must be strings or lists of strings. Found )r4   r   r^   	TypeErrortype__name__)ra   itemsubitems      r   _validate_metarj     s    |$   dD!! 	  !'3// #G!%g!7G G;BG G   D#&& 	9d,9 9049 9  	 r   pandasraisedict | list[dict] | Seriesrecord_pathstr | list | Nonemeta_prefix
str | Nonerecord_prefixerrorsr   r   c                   t          |           	 d"d#fd
d$fdt          | t                    r| j        }nd}t          | t                    r| st                      S t          | t                    r| g} nt          | t          j                  rt          | t                    st	          |           } t          |           D ]i\  }	}
t          |
t                    rt          |
          rt          j        |
          ri | |	<   Ddt          |
          j         }t!          |          nt"          |(|&|$" t          t%          |           |          S |Yt'          d | D                       rt)          |           } t          | |          }|                    fd          }|S t          |t                    s|g}|g }nt          |t                    s|g}d |D             g g t-          t                    fdD             d%d&f
d | |i d           t                    }|                    fd          }                                D ]\  }}|||z   }||v rt1          d| d          t3          j        |t6                     }|j        d!k    rCt3          j        t=          |          ft6                     }t          |          D ]
\  }	}|||	<   |                              ||<   ||                              |_        |S )'a>  
    Normalize semi-structured JSON data into a flat table.

    This method is designed to transform semi-structured JSON data, such as nested
    dictionaries or lists, into a flat table. This is particularly useful when
    handling JSON-like data structures that contain deeply nested fields.

    Parameters
    ----------
    data : dict, list of dicts, or Series of dicts
        Unserialized JSON objects.
    record_path : str or list of str, default None
        Path in each object to list of records. If not passed, data will be
        assumed to be an array of records.
    meta : list of paths (str or list of str), default None
        Fields to use as metadata for each record in resulting table.
    meta_prefix : str, default None
        String to prefix records with dotted path, e.g. foo.bar.field if
        meta is ['foo', 'bar'].
    record_prefix : str, default None
        String to prefix records with dotted path, e.g. foo.bar.field if
        path to records is ['foo', 'bar'].
    errors : {'raise', 'ignore'}, default 'raise'
        Configures error handling.

        * 'ignore' : will ignore KeyError if keys listed in meta are not
          always present.
        * 'raise' : will raise KeyError if keys listed in meta are not
          always present.
    sep : str, default '.'
        Nested records will generate names separated by sep.
        e.g., for sep='.', {'foo': {'bar': 0}} -> foo.bar.
    max_level : int, default None
        Max number of levels(depth of dict) to normalize.
        if None, normalizes all levels.

    Returns
    -------
    DataFrame
        The normalized data, represented as a pandas DataFrame.

    See Also
    --------
    DataFrame : Two-dimensional, size-mutable, potentially heterogeneous tabular data.
    Series : One-dimensional ndarray with axis labels (including time series).

    Examples
    --------
    >>> data = [
    ...     {"id": 1, "name": {"first": "Coleen", "last": "Volk"}},
    ...     {"name": {"given": "Mark", "family": "Regner"}},
    ...     {"id": 2, "name": "Faye Raker"},
    ... ]
    >>> pd.json_normalize(data)
        id name.first name.last name.given name.family        name
    0  1.0     Coleen      Volk        NaN         NaN         NaN
    1  NaN        NaN       NaN       Mark      Regner         NaN
    2  2.0        NaN       NaN        NaN         NaN  Faye Raker

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> pd.json_normalize(data, max_level=0)
        id        name                        fitness
    0  1.0   Cole Volk  {'height': 130, 'weight': 60}
    1  NaN    Mark Reg  {'height': 130, 'weight': 60}
    2  2.0  Faye Raker  {'height': 130, 'weight': 60}

    Normalizes nested data up to level 1.

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> pd.json_normalize(data, max_level=1)
        id        name  fitness.height  fitness.weight
    0  1.0   Cole Volk             130              60
    1  NaN    Mark Reg             130              60
    2  2.0  Faye Raker             130              60

    >>> data = [
    ...     {
    ...         "id": 1,
    ...         "name": "Cole Volk",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ...     {"name": "Mark Reg", "fitness": {"height": 130, "weight": 60}},
    ...     {
    ...         "id": 2,
    ...         "name": "Faye Raker",
    ...         "fitness": {"height": 130, "weight": 60},
    ...     },
    ... ]
    >>> series = pd.Series(data, index=pd.Index(["a", "b", "c"]))
    >>> pd.json_normalize(series)
        id        name  fitness.height  fitness.weight
    a  1.0   Cole Volk             130              60
    b  NaN    Mark Reg             130              60
    c  2.0  Faye Raker             130              60

    >>> data = [
    ...     {
    ...         "state": "Florida",
    ...         "shortname": "FL",
    ...         "info": {"governor": "Rick Scott"},
    ...         "counties": [
    ...             {"name": "Dade", "population": 12345},
    ...             {"name": "Broward", "population": 40000},
    ...             {"name": "Palm Beach", "population": 60000},
    ...         ],
    ...     },
    ...     {
    ...         "state": "Ohio",
    ...         "shortname": "OH",
    ...         "info": {"governor": "John Kasich"},
    ...         "counties": [
    ...             {"name": "Summit", "population": 1234},
    ...             {"name": "Cuyahoga", "population": 1337},
    ...         ],
    ...     },
    ... ]
    >>> result = pd.json_normalize(
    ...     data, "counties", ["state", "shortname", ["info", "governor"]]
    ... )
    >>> result
             name  population    state shortname info.governor
    0        Dade       12345   Florida    FL    Rick Scott
    1     Broward       40000   Florida    FL    Rick Scott
    2  Palm Beach       60000   Florida    FL    Rick Scott
    3      Summit        1234   Ohio       OH    John Kasich
    4    Cuyahoga        1337   Ohio       OH    John Kasich

    >>> data = {"A": [1, 2]}
    >>> pd.json_normalize(data, "A", record_prefix="Prefix.")
        Prefix.0
    0          1
    1          2

    Returns normalized data with columns prefixed with the given string.
    Fjsr&   spec
list | strextract_recordboolr   Scalar | Iterablec                4   | }	 t          |t                    r|D ]}|t          |          ||         }n||         }nV# t          $ rI}|rt          d| d          |dk    rt          j        cY d}~S t          d| d| d          |d}~ww xY w|S )zInternal function to pull fieldNzKey zS not found. If specifying a record_path, all elements of data should have the path.ignorez) not found. To replace missing values of z% with np.nan, pass in errors='ignore')r4   r^   KeyErrornpnan)ru   rv   rx   resultfielders   s         r   _pull_fieldz#json_normalize.<locals>._pull_field  s    	$%% &! + +E~&uoo-#E]FF+
   	 	 	 21 2 2 2   !!v71 7 7q 7 7 7  	 s#   <A 
B'B3B9BBr^   c                     | |d          }t          |t                    s>t          j        |          rg }n't	          dt          |          j         d|          |S )z
        Internal function to pull field for records, and similar to
        _pull_field, but require to return list. And will raise error
        if has non iterable value.
        T)rx   z(Path must contain list or null, but got z at )r4   r^   pdisnullre   rf   rg   )ru   rv   r   r   s      r   _pull_recordsz%json_normalize.<locals>._pull_records  s     Rd;;; &$'' 	y   C#F||4C C:>C C   r   Nz9All items in data must be of type dict or NA-like, found rZ   )indexc              3  R   K   | ]"}d  |                                 D             V  #dS )c                8    g | ]}t          |t                    S r)   rO   )rQ   xs     r   r]   z,json_normalize.<locals>.<genexpr>.<listcomp>5  s"    888
1d##888r   N)values)rQ   ys     r   	<genexpr>z!json_normalize.<locals>.<genexpr>5  s9      GGQ88QXXZZ888GGGGGGr   r!   r$   c                     |  S r(   r)   r   rr   s    r   <lambda>z json_normalize.<locals>.<lambda>@  s    5Jq5J5J r   )columnsc                B    g | ]}t          |t                    r|n|gS r)   )r4   r^   )rQ   ms     r   r]   z"json_normalize.<locals>.<listcomp>J  s-    ===1*Q%%.QQA3===r   c                :    g | ]}                     |          S r)   )join)rQ   valr!   s     r   r]   z"json_normalize.<locals>.<listcomp>Q  s#    0003#000r   r   r"   r#   rc   c                  
 t          | t                    r| g} t          |          dk    rp| D ]k}t          	d          D ]0\  }}|dz   t          |          k    r 
||d                   ||<   1 ||d                  |dd          ||dz              ld S | D ]} ||d                   }fd|D             }                    t          |                     t          	d          D ]S\  }}|dz   t          |          k    r	||         }n 
|||d                    }|                             |           T                    |           d S )Nr   T)strictr   r   r"   c                b    g | ]+}t          |t                    rt          |           n|,S )r   )r4   r   r+   )rQ   rr$   r!   s     r   r]   z>json_normalize.<locals>._recursive_extract.<locals>.<listcomp>`  sR         "!T**$QC9EEEE  r   )r4   r   lenzipr:   extend)rB   path	seen_metar"   objr   rJ   recsmeta_val_metar   r   _recursive_extractlengthsr$   	meta_keys	meta_valsrecordsr!   s            r   r   z*json_normalize.<locals>._recursive_extractS  s   dD!! 	6Dt99q== W W #E9T B B B C CHCqyCHH,,)4S#b')B)B	#""3tAw<abb9ETUIVVVVVW W  % %$}S$q'22     "	   s4yy))) #E9T B B B 4 4HCqy3s88++#,S>#.;sCK#@#@cN))(3333t$$$$#% %r   r   c                     |  S r(   r)   r   s    r   r   z json_normalize.<locals>.<lambda>v  s    M1F11F1F r   zConflicting metadata name z, need distinguishing prefix )dtyper   )F)ru   r&   rv   rw   rx   ry   r   rz   )ru   r&   rv   rw   r   r^   )r   )r"   r#   r   rc   ) rj   r4   r   r   r^   r   r   r   r   r   	enumerater   r   isnarf   rg   re   NotImplementedErrorr[   anyr+   renamer   r7   
ValueErrorr~   arrayobjectndimemptyr   repeat)rB   rn   ra   rp   rr   rs   r!   r$   r   irh   msgr   r?   r@   r   r   r   r   r   r   r   r   r   r   s       ````         @@@@@@@@r   json_normalizer   /  sL   T 4 FK      :     ( $ 
$ "d "{{	D$		 "v	D#,	'	' "
40E0E " Dzz  
	% 
	%GAt$%%  %274== %Q3!$ZZ03 3   nn$
	% "! 	L!/#>>>eLLLLGG$GGGGG 	H $DcYGGGD4u---$]]+J+J+J+J]KKFT** $"m|d## v=====E GG(..I0000%000I% % % % % % % % % % % % % % % %< t["A6666wF 'F'F'F'FGG !! + +1"aA;;MQMMM  
 !6***;??Xs1vviv666F#A,,    3q		MM'**q		||G,,Mr   )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   r-   )r/   r0   r   N)r   r1   r    r   r!   r   r"   r#   r$   r%   r   r2   )
rB   r   rC   r   rD   r&   rE   r   r   r&   )rB   r&   rE   r   r   r&   )r0   )r   r1   r!   r   r   rW   )ra   rb   r   rc   )NNNNrl   r0   N)rB   rm   rn   ro   ra   rb   rp   rq   rr   rq   rs   r   r!   r   r$   r%   r   r   )#
__future__r   collectionsr   r   r5   typingr   r   r   r	   numpyr~   pandas._libs.writersr   pandas.util._decoratorsr   pandas.core.dtypes.commonr   rk   r   r   r   collections.abcr   pandas._typingr   r   r   r+   rI   rV   r[   rj   r   r)   r   r   <module>r      s   # " " " " "                        6 6 6 6 6 6 . . . . . . / / / / / /           
  ((((((       
$ 
$ 
$ 
$ 
     
 
     
  N N N N Nb& & & &R) ) ) )6 2" 2" 2" 2" 2"j   > H &*/3" $! ^ ^ ^ ^ ^ ^ ^r   