zmc
2023-08-08 e792e9a60d958b93aef96050644f369feb25d61b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
U
¬ý°dV}ã@s¼dZddlmZddlZddlZddlmZddlZddl    m
Z
m Z m Z m Z mZddlZddlZddlZddlmZmZmZmZddlmZddlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&dd    l'm(Z(dd
l)m*Z*m+Z+m,Z,dd l-m.Z.dd l/m0Z0dd l1m2Z2ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDddlEmFZFddlGmHZHmIZIddlJmKZKmLZLddlMmNZNmOZOmPZPmQZQmRZRddlSmTmUZVddlWmXZXmYZYmZZZddl[m\Z\ddl]mTm^Z_ddl`maZambZbddlcmdZdddlemfZfddlgmhZhe
r6ddlMmiZiddljmkZkddlWmlZlejmejnejoejnejpejqejrejsejtejuejvejwejxejyejzej{ej|ej}ej~ej}ejej€ejej‚ejƒej„ej…ej†ej‡ejˆiZ‰e+dƒe*eddddƒd!d!d"d#d#d#d$d$d$d%d&d'd(d)d*œd+d,„ƒƒZŠd)d)d-œd.d/„Z‹d„d)d)d#d#d#d(d%d1d)d2œ    d3d4„ZŒd…d!d!d#d#d#d$d$d%d$d7d)d8œ d9d:„ZGd;d<„d<ƒZŽd†d$d=d>d?œd@dA„ZdBdBdCdDdDdEdFœdGdH„ZGdIdJ„dJeŽƒZ‘d7dKœdLdM„Z’e5e4e6dNœZ“dOd7dPœdQdR„Z”GdSdT„dTe‘ƒZ•dBd$d>dUœdVdW„Z–d‡dCd$d>dUœdXdY„Z—d>dZœd[d\„Z˜d]d$d>d^œd_d`„Z™dˆdCdCd$dadbœdcdd„Zšd‰deded$d=dfdgœdhdi„Z›dededjdkœdldm„ZœdndDdDd>doœdpdq„Zdrdrdsd$dtduœdvdw„Zžd$dZœdxdy„ZŸd$dZœdzd{„Z d!d)d|œd}d~„Z¡dCdCd%dd€œdd‚„Z¢dS)Šz
SQL-style merge routines
é)Ú annotationsN)Úpartial)Ú TYPE_CHECKINGÚHashableÚLiteralÚSequenceÚcast)Ú    TimedeltaÚ    hashtableÚjoinÚlib)Úis_range_indexer)
Ú AnyArrayLikeÚ    ArrayLikeÚAxisIntÚDtypeObjÚ
IndexLabelÚJoinHowÚMergeHowÚShapeÚSuffixesÚnpt)Ú
MergeError)ÚAppenderÚ SubstitutionÚcache_readonly)Úfind_stack_level)ÚExtensionDtype)Úfind_common_type)Úensure_float64Ú ensure_int64Ú ensure_objectÚ is_array_likeÚis_boolÚ is_bool_dtypeÚis_categorical_dtypeÚis_dtype_equalÚis_extension_array_dtypeÚis_float_dtypeÚ
is_integerÚis_integer_dtypeÚ is_list_likeÚ    is_numberÚis_numeric_dtypeÚis_object_dtypeÚneeds_i8_conversion)ÚDatetimeTZDtype)Ú ABCDataFrameÚ    ABCSeries)ÚisnaÚna_value_for_dtype)Ú
ArrowDtypeÚ CategoricalÚIndexÚ
MultiIndexÚSeries)ÚArrowExtensionArrayÚBaseMaskedArrayÚExtensionArray)ÚNDArrayBackedExtensionArray)Úensure_wrapped_if_datetimelikeÚ extract_array)Ú
_merge_doc)Ú default_index©Úis_int64_overflow_possible)Ú    DataFrame)Úgroupby)Ú DatetimeArrayz!
left : DataFrame or named Series)ÚindentsÚinnerF©Ú_xZ_yúDataFrame | SeriesrúIndexLabel | NoneÚboolrú bool | Noneú
str | boolú
str | NonerD)ÚleftÚrightÚhowÚonÚleft_onÚright_onÚ
left_indexÚ right_indexÚsortÚsuffixesÚcopyÚ    indicatorÚvalidateÚreturnc Cs,t||||||||||    | | d } | j|
dS)N)
rSrTrUrVrWrXrYrZr\r]©r[)Ú_MergeOperationÚ
get_result)rQrRrSrTrUrVrWrXrYrZr[r\r]Úop©rcúPd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\pandas/core/reshape/merge.pyÚmergesôre©rQrRc    s>g}t|ttfƒs|g}|j|dd}d}t‡fdd„|DƒƒrNˆj|dd}|jj|j|jdD]¦\}}|dkrxˆ}    ntzˆ     |j
|¡}    Wn^t k
rê|j   ¡‰ˆ‡fdd„ˆj Dƒ}
|j|
d    } tt| ƒƒ| _| | ¡YqbYnX|||    ƒ} || |<| | ¡qbd
d lm} | |d d } | j|d
j dd} | |fS)zÒ
    groupby & merge; we are always performing a left-by type operation
 
    Parameters
    ----------
    by: field to group
    left: DataFrame
    right: DataFrame
    merge_pieces: function for merging
    F©rYNc3s|]}|ˆjkVqdS©N©Úcolumns)Ú.0Úitem©rRrcrdÚ    <genexpr>µsz%_groupby_and_merge.<locals>.<genexpr>)Úaxiscsg|]}|tˆƒkr|‘qSrc)Úset)rkÚr)ÚlcolsrcrdÚ
<listcomp>Ás z&_groupby_and_merge.<locals>.<listcomp>rir©ÚconcatT)Z ignore_index)rjr[)Ú
isinstanceÚlistÚtuplerEÚallZgrouperZ get_iteratorZ _selected_objroÚtakeÚindicesÚKeyErrorrjÚtolistZreindexÚrangeÚlenÚindexÚappendZpandas.core.reshape.concatru)ÚbyrQrRZ merge_piecesÚpiecesZlbyZrbyÚkeyÚlhsÚrhsÚcolsÚmergedruÚresultrc)rrrRrdÚ_groupby_and_merge¡s4 
 
 
 
   rŠÚouterr)    rQrRrTrUrVÚ fill_methodrZrSr^c
sþddœ‡‡‡‡‡‡fdd„ ‰|dk    r4|dk    r4tdƒ‚|dk    r’t|tƒrL|g}t|ƒ |j¡}
t|
ƒdkrvt|
›dƒ‚t|||‡fd    d
„ƒ\} } nh|dk    rðt|tƒrª|g}t|ƒ |j¡}
t|
ƒdkrÔt|
›d ƒ‚t|||‡fd d
„ƒ\} } n
ˆ||ƒ} | S) a1
    Perform a merge for ordered data with optional filling/interpolation.
 
    Designed for ordered data like time series data. Optionally
    perform group-wise merge (see examples).
 
    Parameters
    ----------
    left : DataFrame or named Series
    right : DataFrame or named Series
    on : label or list
        Field names to join on. Must be found in both DataFrames.
    left_on : label or list, or array-like
        Field names to join on in left DataFrame. Can be a vector or list of
        vectors of the length of the DataFrame to use a particular vector as
        the join key instead of columns.
    right_on : label or list, or array-like
        Field names to join on in right DataFrame or vector/list of vectors per
        left_on docs.
    left_by : column name or list of column names
        Group left DataFrame by group columns and merge piece by piece with
        right DataFrame. Must be None if either left or right are a Series.
    right_by : column name or list of column names
        Group right DataFrame by group columns and merge piece by piece with
        left DataFrame. Must be None if either left or right are a Series.
    fill_method : {'ffill', None}, default None
        Interpolation method for data.
    suffixes : list-like, default is ("_x", "_y")
        A length-2 sequence where each element is optionally a string
        indicating the suffix to add to overlapping column names in
        `left` and `right` respectively. Pass a value of `None` instead
        of a string to indicate that the column name from `left` or
        `right` should be left as-is, with no suffix. At least one of the
        values must not be None.
 
    how : {'left', 'right', 'outer', 'inner'}, default 'outer'
        * left: use only keys from left frame (SQL: left outer join)
        * right: use only keys from right frame (SQL: right outer join)
        * outer: use union of keys from both frames (SQL: full outer join)
        * inner: use intersection of keys from both frames (SQL: inner join).
 
    Returns
    -------
    DataFrame
        The merged DataFrame output type will be the same as
        'left', if it is a subclass of DataFrame.
 
    See Also
    --------
    merge : Merge with a database-style join.
    merge_asof : Merge on nearest keys.
 
    Examples
    --------
    >>> from pandas import merge_ordered
    >>> df1 = pd.DataFrame(
    ...     {
    ...         "key": ["a", "c", "e", "a", "c", "e"],
    ...         "lvalue": [1, 2, 3, 1, 2, 3],
    ...         "group": ["a", "a", "a", "b", "b", "b"]
    ...     }
    ... )
    >>> df1
          key  lvalue group
    0   a       1     a
    1   c       2     a
    2   e       3     a
    3   a       1     b
    4   c       2     b
    5   e       3     b
 
    >>> df2 = pd.DataFrame({"key": ["b", "c", "d"], "rvalue": [1, 2, 3]})
    >>> df2
          key  rvalue
    0   b       1
    1   c       2
    2   d       3
 
    >>> merge_ordered(df1, df2, fill_method="ffill", left_by="group")
      key  lvalue group  rvalue
    0   a       1     a     NaN
    1   b       1     a     1.0
    2   c       2     a     2.0
    3   d       2     a     3.0
    4   e       3     a     3.0
    5   a       1     b     NaN
    6   b       1     b     1.0
    7   c       2     b     2.0
    8   d       2     b     3.0
    9   e       3     b     3.0
    rD©r^c
s t||ˆˆˆˆˆˆd}| ¡S)N)rTrUrVrZrŒrS)Ú _OrderedMergera)ÚxÚyrb)rŒrSrUrTrVrZrcrdÚ_merger@sø
zmerge_ordered.<locals>._mergerNz*Can only group either left or right framesrz not found in left columnscs
ˆ||ƒSrhrc©rr©r‘rcrdÚ<lambda>Vózmerge_ordered.<locals>.<lambda>z not found in right columnscs
ˆ||ƒSrhrcr’r“rcrdr”^r•)    Ú
ValueErrorrvÚstrrpÚ
differencerjrr|rŠ) rQrRrTrUrVÚleft_byÚright_byrŒrZrSÚcheckr‰Ú_rc)r‘rŒrSrUrTrVrZrdÚ merge_orderedØs0h
 
 
ÿ
 
rTÚbackwardr—) rQrRrTrUrVrWrXrZÚallow_exact_matchesÚ    directionr^cCs.t||||||||||    |
d| | | d}| ¡S)a'#
    Perform a merge by key distance.
 
    This is similar to a left-join except that we match on nearest
    key rather than equal keys. Both DataFrames must be sorted by the key.
 
    For each row in the left DataFrame:
 
      - A "backward" search selects the last row in the right DataFrame whose
        'on' key is less than or equal to the left's key.
 
      - A "forward" search selects the first row in the right DataFrame whose
        'on' key is greater than or equal to the left's key.
 
      - A "nearest" search selects the row in the right DataFrame whose 'on'
        key is closest in absolute distance to the left's key.
 
    The default is "backward" and is compatible in versions below 0.20.0.
    The direction parameter was added in version 0.20.0 and introduces
    "forward" and "nearest".
 
    Optionally match on equivalent keys with 'by' before searching with 'on'.
 
    Parameters
    ----------
    left : DataFrame or named Series
    right : DataFrame or named Series
    on : label
        Field name to join on. Must be found in both DataFrames.
        The data MUST be ordered. Furthermore this must be a numeric column,
        such as datetimelike, integer, or float. On or left_on/right_on
        must be given.
    left_on : label
        Field name to join on in left DataFrame.
    right_on : label
        Field name to join on in right DataFrame.
    left_index : bool
        Use the index of the left DataFrame as the join key.
    right_index : bool
        Use the index of the right DataFrame as the join key.
    by : column name or list of column names
        Match on these columns before performing merge operation.
    left_by : column name
        Field names to match on in the left DataFrame.
    right_by : column name
        Field names to match on in the right DataFrame.
    suffixes : 2-length sequence (tuple, list, ...)
        Suffix to apply to overlapping column names in the left and right
        side, respectively.
    tolerance : int or Timedelta, optional, default None
        Select asof tolerance within this range; must be compatible
        with the merge index.
    allow_exact_matches : bool, default True
 
        - If True, allow matching with the same 'on' value
          (i.e. less-than-or-equal-to / greater-than-or-equal-to)
        - If False, don't match the same 'on' value
          (i.e., strictly less-than / strictly greater-than).
 
    direction : 'backward' (default), 'forward', or 'nearest'
        Whether to search for prior, subsequent, or closest matches.
 
    Returns
    -------
    DataFrame
 
    See Also
    --------
    merge : Merge with a database-style join.
    merge_ordered : Merge with optional filling/interpolation.
 
    Examples
    --------
    >>> left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})
    >>> left
        a left_val
    0   1        a
    1   5        b
    2  10        c
 
    >>> right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})
    >>> right
       a  right_val
    0  1          1
    1  2          2
    2  3          3
    3  6          6
    4  7          7
 
    >>> pd.merge_asof(left, right, on="a")
        a left_val  right_val
    0   1        a          1
    1   5        b          3
    2  10        c          7
 
    >>> pd.merge_asof(left, right, on="a", allow_exact_matches=False)
        a left_val  right_val
    0   1        a        NaN
    1   5        b        3.0
    2  10        c        7.0
 
    >>> pd.merge_asof(left, right, on="a", direction="forward")
        a left_val  right_val
    0   1        a        1.0
    1   5        b        6.0
    2  10        c        NaN
 
    >>> pd.merge_asof(left, right, on="a", direction="nearest")
        a left_val  right_val
    0   1        a          1
    1   5        b          6
    2  10        c          7
 
    We can use indexed DataFrames as well.
 
    >>> left = pd.DataFrame({"left_val": ["a", "b", "c"]}, index=[1, 5, 10])
    >>> left
       left_val
    1         a
    5         b
    10        c
 
    >>> right = pd.DataFrame({"right_val": [1, 2, 3, 6, 7]}, index=[1, 2, 3, 6, 7])
    >>> right
       right_val
    1          1
    2          2
    3          3
    6          6
    7          7
 
    >>> pd.merge_asof(left, right, left_index=True, right_index=True)
       left_val  right_val
    1         a          1
    5         b          3
    10        c          7
 
    Here is a real-world times-series example
 
    >>> quotes = pd.DataFrame(
    ...     {
    ...         "time": [
    ...             pd.Timestamp("2016-05-25 13:30:00.023"),
    ...             pd.Timestamp("2016-05-25 13:30:00.023"),
    ...             pd.Timestamp("2016-05-25 13:30:00.030"),
    ...             pd.Timestamp("2016-05-25 13:30:00.041"),
    ...             pd.Timestamp("2016-05-25 13:30:00.048"),
    ...             pd.Timestamp("2016-05-25 13:30:00.049"),
    ...             pd.Timestamp("2016-05-25 13:30:00.072"),
    ...             pd.Timestamp("2016-05-25 13:30:00.075")
    ...         ],
    ...         "ticker": [
    ...                "GOOG",
    ...                "MSFT",
    ...                "MSFT",
    ...                "MSFT",
    ...                "GOOG",
    ...                "AAPL",
    ...                "GOOG",
    ...                "MSFT"
    ...            ],
    ...            "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
    ...            "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03]
    ...     }
    ... )
    >>> quotes
                         time ticker     bid     ask
    0 2016-05-25 13:30:00.023   GOOG  720.50  720.93
    1 2016-05-25 13:30:00.023   MSFT   51.95   51.96
    2 2016-05-25 13:30:00.030   MSFT   51.97   51.98
    3 2016-05-25 13:30:00.041   MSFT   51.99   52.00
    4 2016-05-25 13:30:00.048   GOOG  720.50  720.93
    5 2016-05-25 13:30:00.049   AAPL   97.99   98.01
    6 2016-05-25 13:30:00.072   GOOG  720.50  720.88
    7 2016-05-25 13:30:00.075   MSFT   52.01   52.03
 
    >>> trades = pd.DataFrame(
    ...        {
    ...            "time": [
    ...                pd.Timestamp("2016-05-25 13:30:00.023"),
    ...                pd.Timestamp("2016-05-25 13:30:00.038"),
    ...                pd.Timestamp("2016-05-25 13:30:00.048"),
    ...                pd.Timestamp("2016-05-25 13:30:00.048"),
    ...                pd.Timestamp("2016-05-25 13:30:00.048")
    ...            ],
    ...            "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
    ...            "price": [51.95, 51.95, 720.77, 720.92, 98.0],
    ...            "quantity": [75, 155, 100, 100, 100]
    ...        }
    ...    )
    >>> trades
                         time ticker   price  quantity
    0 2016-05-25 13:30:00.023   MSFT   51.95        75
    1 2016-05-25 13:30:00.038   MSFT   51.95       155
    2 2016-05-25 13:30:00.048   GOOG  720.77       100
    3 2016-05-25 13:30:00.048   GOOG  720.92       100
    4 2016-05-25 13:30:00.048   AAPL   98.00       100
 
    By default we are taking the asof of the quotes
 
    >>> pd.merge_asof(trades, quotes, on="time", by="ticker")
                         time ticker   price  quantity     bid     ask
    0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
    1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
    2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
    3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
    4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
 
    We only asof within 2ms between the quote time and the trade time
 
    >>> pd.merge_asof(
    ...     trades, quotes, on="time", by="ticker", tolerance=pd.Timedelta("2ms")
    ... )
                         time ticker   price  quantity     bid     ask
    0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
    1 2016-05-25 13:30:00.038   MSFT   51.95       155     NaN     NaN
    2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
    3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
    4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
 
    We only asof within 10ms between the quote time and the trade time
    and we exclude exact matches on time. However *prior* data will
    propagate forward
 
    >>> pd.merge_asof(
    ...     trades,
    ...     quotes,
    ...     on="time",
    ...     by="ticker",
    ...     tolerance=pd.Timedelta("10ms"),
    ...     allow_exact_matches=False
    ... )
                         time ticker   price  quantity     bid     ask
    0 2016-05-25 13:30:00.023   MSFT   51.95        75     NaN     NaN
    1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
    2 2016-05-25 13:30:00.048   GOOG  720.77       100     NaN     NaN
    3 2016-05-25 13:30:00.048   GOOG  720.92       100     NaN     NaN
    4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
    Úasof) rTrUrVrWrXr‚r™ršrZrSÚ    tolerancerŸr )Ú
_AsOfMergera)rQrRrTrUrVrWrXr‚r™ršrZr¢rŸr rbrcrcrdÚ
merge_asofes(ñr¤c@sÌeZdZUdZdZded<ded<ded<ded    <d
ed <d
ed <d ed<d ed<d
ed<ded<d
ed<ded<ded<ded<ded<ded<d_d#d#ddddd d
d
d
dddd$d%œd&d'„Zd(d)d)d*d+d,œd-d.„Zd`d*d+d/œd0d1„Zd+dd$d2œd3d4„Z    e
dd5œd6d7„ƒZ d+d+d8d9œd:d;„Z d+d+d<œd=d>„Z d+d$d<œd?d@„Zd+dAdAd$dBœdCdD„ZdEd5œdFdG„ZdHd5œdIdJ„Zdad(d(dLdMd(dNœdOdP„ZdQd5œdRdS„Zd$d5œdTdU„Zd+d+dVd9œdWdX„ZdYdZ„Zd[d$d\œd]d^„ZdS)br`z
    Perform a database (SQL) merge operation between two DataFrame or Series
    objects using either columns as keys or their row indexes
    reúMergeHow | Literal['asof']rSrLrTz!Sequence[Hashable | AnyArrayLike]rUrVrMrWrXrroÚbm_axisrYrrZr[rOr\rPr]zlist[Hashable]Ú
join_nameszlist[AnyArrayLike]Úright_join_keysÚleft_join_keysrHNéFTrIrKÚNone)rQrRrSrTrUrVrorWrXrYrZr\r]r^cCsht|ƒ}t|ƒ}||_|_||_|_||_||_|jjdkrHd|nd|_t     
|¡|_ | |_ |
|_ ||_|    |_| |_t|ƒs’tdt|ƒ›ƒ‚t|    ƒs¬tdt|    ƒ›ƒ‚|jj|jjkrÞd|jj›d|jj›d}t|ƒ‚| ||¡\|_|_d}|jd    kr.| |j|j¡\|_|_|_}|g|_|_||_| ¡\|_|_|_|  ¡| dk    rd| !| ¡dS)
Nérªrz/left_index parameter must be of type bool, not z0right_index parameter must be of type bool, not z0Not allowed to merge between different levels. (z levels on the left, z on the right)Úcross)"Ú_validate_operandrQÚ    orig_leftrRÚ
orig_rightrSr¦ÚndimroÚcomÚmaybe_make_listrTrZrYrWrXr\r#r–ÚtyperjÚnlevelsrÚ_validate_left_right_onrUrVÚ_create_cross_configurationÚ_crossÚ_get_merge_keysr©r¨r§Ú_maybe_coerce_merge_keysÚ    _validate)ÚselfrQrRrSrTrUrVrorWrXrYrZr\r]Ú_leftZ_rightÚmsgÚ    cross_colrcrcrdÚ__init__”sX    ÿ ÿÿ ûü
z_MergeOperation.__init__r7znpt.NDArray[np.intp] | NonerNrD)Ú
join_indexÚ left_indexerÚ right_indexerr[r^c     Csä|jdd…}|jdd…}t|jj|jj|jƒ\}}|dk    rpt|t|ƒƒsp|jj||dddddd}    |     |    ¡}||_
|dk    r°t|t|ƒƒs°|jj||dddddd}
|     |
¡}||_
ddl m } ||_ ||_ | ||gd|d} | S)    z?
        reindex along index and concat along columns.
        NrªFT)ror[Z
only_sliceZ
allow_dupsZ use_na_proxyrrt)ror[)rQrRÚ_items_overlap_with_suffixÚ
_info_axisrZr rZ_mgrZreindex_indexerZ _constructorr€Úpandasrurj) r¼rÁrÂrÃr[rQrRÚllabelsÚrlabelsZlmgrZrmgrrur‰rcrcrdÚ_reindex_and_concatésN ÿù    
 
ÿù    
 z#_MergeOperation._reindex_and_concat©r[r^cCs’|jr| |j|j¡\|_|_| ¡\}}}|j||||d}|j||jd}|jr^| |¡}|     |||¡| 
|¡|  ||j ¡|j|ddS)Nr_)Úmethodre) r\Ú_indicator_pre_mergerQrRÚ_get_join_inforÉZ __finalize__Ú _merge_typeÚ_indicator_post_mergeÚ_maybe_add_join_keysÚ_maybe_restore_index_levelsÚ_maybe_drop_cross_columnr¸)r¼r[rÁrÂrÃr‰rcrcrdra!s ÿ
 
z_MergeOperation.get_result)r‰r¿r^cCs|dk    r||=dSrhrc)r¼r‰r¿rcrcrdrÒ7sz(_MergeOperation._maybe_drop_cross_columnrcCs8t|jtƒr|jSt|jtƒr,|jr(dSdStdƒ‚dS)NZ_mergez<indicator option can only accept boolean or string arguments)rvr\r—rMr–©r¼rcrcrdÚ_indicator_name=s  ÿz_MergeOperation._indicator_nameztuple[DataFrame, DataFrame])rQrRr^cCsŒ|j |j¡}dD]}||krtd|›ƒ‚q|j|kr@tdƒ‚| ¡}| ¡}d|d<|d d¡|d<d|d<|d d¡|d<||fS)    N)Ú_left_indicatorÚ_right_indicatorzECannot use `indicator=True` option when data contains a column named z:Cannot use name of an existing column for indicator columnrªrÕÚint8r¬rÖ)rjÚunionr–rÔr[Úastype)r¼rQrRrjÚircrcrdrÌHs"ÿ
ÿz$_MergeOperation._indicator_pre_merge)r‰r^cCs||d d¡|d<|d d¡|d<t|d|ddddgd||j<||jj dd    d
g¡||j<|jddgdd }|S) NrÕrrÖrªr¬é)Ú
categoriesZ    left_onlyZ
right_onlyZboth)Úlabelsro)Zfillnar6rÔÚcatZrename_categoriesZdrop)r¼r‰rcrcrdrÏcsþ ÿþ
z%_MergeOperation._indicator_post_mergecCsng}t|j|j|jƒD]@\}}}|j |¡r|j |¡r||kr||jjkr|     |¡q|rj|j
|dddS)a
        Restore index levels specified as `on` parameters
 
        Here we check for cases where `self.left_on` and `self.right_on` pairs
        each reference an index level in their respective DataFrames. The
        joined columns corresponding to these pairs are then restored to the
        index of `result`.
 
        **Note:** This method has side effects. It modifies `result` in-place
 
        Parameters
        ----------
        result: DataFrame
            merge result
 
        Returns
        -------
        None
        T©ZinplaceN) Úzipr§rUrVr¯Ú_is_level_referencer°r€ÚnamesrÚ    set_index)r¼r‰Znames_to_restoreÚnameÚleft_keyÚ    right_keyrcrcrdrÑrs&ÿ
üÿø õ
ô z+_MergeOperation._maybe_restore_index_levelsznp.ndarray | None)r‰rÂrÃr^csÖd}d}tdd„|jDƒƒs t‚t|j|j|jƒ}t|ƒD]”\}\‰}}    t||    ƒsVq:d\}
} ˆˆkr&|dk    rD|dk    rDˆ|j    krÎ|dkrš|dk 
¡}|rÌ|j |} t ˆˆj |j    ˆj ƒsÌ|j    ˆj}
nVˆ|jkrD|dkrî|dk 
¡}|rD|j|}
t ˆˆj |jˆj ƒsD|jˆj} n|dk    rD|j|}
|j |} |
dk    sV| dk    r:|
dkrlˆˆj} n&t|
dd}
t|
j ƒ} tj|
|| d} | dkr¨ˆˆj}n&t| dd}t|j ƒ}tj|||d}|dk}| ¡rðt|ƒ‰|j }nJ|dk    r|dk ¡rt| ƒ‰| j }n"t| ƒ ||¡‰t| j |j gƒ}ˆ ˆ¡r\tˆ|ˆjdˆˆ<q:ˆ ˆ¡r¶tˆjtƒr¦ˆˆ_‡‡‡fd    d
„ˆjjDƒ}ˆj|dd ntˆˆd ˆ_q:ˆ  |ˆpÊd |›ˆ¡q:dS)Ncss|]}t|ƒVqdSrh)r"©rkrrcrcrdrn¦sz7_MergeOperation._maybe_add_join_keys.<locals>.<genexpr>)NNéÿÿÿÿT©Ú extract_numpy©Ú
fill_value)Údtyper€cs$g|]}|ˆkrˆj |¡nˆ‘qSrc)r€Úget_level_values)rkZ
level_name©Zkey_colrär‰rcrdrsósþÿz8_MergeOperation._maybe_add_join_keys.<locals>.<listcomp>rß)räÚkey_)!ryr©ÚAssertionErrorràr§rUrVÚ    enumerateÚ _should_fillrQÚanyr¨r&ríÚ_valuesrRr?r4ÚalgosÚtake_ndr7ÚwhererZ_is_label_referencer9r€rárvr8rärârãÚinsert)r¼r‰rÂrÃZleft_has_missingZright_has_missingÚkeysrÚÚlnameÚrnameZ    take_leftZ
take_rightZlvalsZlfillZrvalsZtakerZrfillZ    mask_leftZ result_dtypeZidx_listrcrïrdrНsˆ
 
 
 
 
ÿ  
 
ÿ
 
 
 
 
 
 
 
 ÿ  üz$_MergeOperation._maybe_add_join_keysú1tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]cCst|j|j|j|jdS)úreturn the join indexers©rYrS)Úget_join_indexersr©r¨rYrSrÓrcrcrdÚ_get_join_indexerss ÿz"_MergeOperation._get_join_indexerszFtuple[Index, npt.NDArray[np.intp] | None, npt.NDArray[np.intp] | None]cCs²|jdkst‚|jj|j}|jj|j}|jr`|jr`|jdkr`|j||jd|j    d\}}}n|jrŒ|jdkrŒt
|||j |j    d\}}}nò|jr¸|jdkr¸t
|||j |j    d\}}}nÆ|  ¡\}}|jrt|jƒdkrö|j|jj|jj|dd    }n|jj |¡}nx|jrr|jdkr6|j|jj|jj|dd    }n:t|jƒdkrb|j|jj|jj|dd    }n|jj |¡}n tt|ƒƒ}t|ƒdkr¨t|tƒs¨tdƒ |j¡}|||fS)
Nr­r¡T)rSZreturn_indexersrYrQrgrRr©rS)rSrñrQZaxesrorRrWrXr rYÚ_left_join_on_indexr©r¨rrÚ_create_join_indexr€rzrArvr8Z    set_namesrä)r¼Úleft_axÚright_axrÁrÂrÃrcrcrdrÍslÿÿÿ ü üü z_MergeOperation._get_join_inforQúnpt.NDArray[np.intp]r)r€Ú other_indexÚindexerrSr^cCsR|j|dfkrHt|tƒsH|dk}t |¡rHt|jdd}| t|gƒ¡}|     |¡S)a«
        Create a join index by rearranging one index to match another
 
        Parameters
        ----------
        index : Index being rearranged
        other_index : Index used to supply values not found in index
        indexer : np.ndarray[np.intp] how to rearrange index
        how : str
            Replacement is only necessary if indexer based on other_index.
 
        Returns
        -------
        Index
        r‹rèF)Úcompat)
rSrvr8Únprôr4rírr7rz)r¼r€rr    rSÚmaskrìrcrcrdrCs 
z"_MergeOperation._create_join_indexú=tuple[list[AnyArrayLike], list[AnyArrayLike], list[Hashable]]c s\g}g}g}g}g}|j|j‰‰‡fdd„}‡fdd„}t|jƒrÜt|jƒrÜt|j|jƒD]t\}}    ||ƒrøtt|ƒ}| |¡||    ƒr®tt|    ƒ}    | |    ¡| d¡nHtt    |    ƒ}    |    dk    rÜ| ˆ 
|    ¡¡| |    ¡n| ˆj ¡| ˆj j ¡q`||    ƒsxtt    |    ƒ}    |    dk    r(| ˆ 
|    ¡¡n | ˆj ¡|dk    rŒ||    krŒtt    |ƒ}t ˆƒdkrl| |    ¡n
| |¡ntt|    ƒ}    | |    ¡|dk    r¼tt    |ƒ}| ˆ 
|¡¡| |¡q`| ˆj ¡| ˆj j ¡q`nNt|jƒr„|jD]T}
||
ƒrtt|
ƒ}
| |
¡| d¡n$tt    |
ƒ}
| ˆ 
|
¡¡| |
¡qît|jj tƒrvdd„t|jj j|jj jƒDƒ}n |jj jg}n¦t|jƒr*|jD]T}
||
ƒrÄtt|
ƒ}
| |
¡| d¡n$tt    |
ƒ}
| ˆ 
|
¡¡| |
¡q–t|jj tƒrdd„t|jj j|jj jƒDƒ}n |jj jg}|r>|j |¡|_|rR|j |¡|_|||fS)    zÚ
        Note: has side effects (copy/delete key columns)
 
        Parameters
        ----------
        left
        right
        on
 
        Returns
        -------
        left_keys, right_keys, join_names
        cst|ƒot|ƒtˆƒkSrh©r"r©r)rQrcrdr”r•z1_MergeOperation._get_merge_keys.<locals>.<lambda>cst|ƒot|ƒtˆƒkSrhrrrmrcrdr”€r•NrcSsg|]\}}|j |¡‘qSrc©rõrz©rkÚlevZ    lev_codesrcrcrdrsÌsÿz3_MergeOperation._get_merge_keys.<locals>.<listcomp>cSsg|]\}}|j |¡‘qSrcrrrcrcrdrsásÿ)rQrRÚ_anyrUrVràrrrrÚ_get_label_or_level_valuesr€rärrvr8ÚlevelsÚcodesrõZ_drop_labels_or_levels) r¼Ú    left_keysÚ
right_keysr§Z
right_dropZ    left_dropZis_lkeyZis_rkeyÚlkÚrkÚkrcrfrdr¹es   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ÿþ 
 
 
 
 
ÿþ z_MergeOperation._get_merge_keysc
Cs
t|j|j|jƒD]ð\}}}t|ƒr.t|ƒrt|ƒs@t|ƒr@qt|dd}t|dd}t|jƒ}t|jƒ}t|jƒ}t|jƒ}|rª|rªt    t
|ƒ}t    t
|ƒ}|  |¡rÄqn|sÄ|r´nt |j|jƒrÄqd|j›d|j›d}t |jƒrt |jƒr|jj|jjkrqt|jƒrxt|jƒrxtjddF| |j¡}    t |¡}
||    k} | |
 ¡sltjdttƒd    W5QRXqt|jƒrêt|jƒrêtjddF| |j¡}    t |¡}
||    k} | |
 ¡sÞtjdttƒd    W5QRXqtj|d
d tj|d
d krvqnh|r t|jƒsvt|jƒr6|r6n@|rHt |jƒsZt |jƒrØ|rØtj|d
d } tj|d
d } d d ddg}dddddg}| |kr¦| |kr¦n0| |krº| |ksÎ| |krv| |krvt|ƒ‚nžt|jƒrút|jƒsút|ƒ‚n|t|jƒst|jƒrt|ƒ‚nZt|jt ƒrBt|jt ƒsBt|ƒ‚n4t|jt ƒsht|jt ƒrht|ƒ‚n|rv|rvq||j!j"kr¾|r˜t    t
|ƒj#jnt$}|j! %¡|_!|j!| |¡|j!|<||j&j"kr|rÞt    t
|ƒj#jnt$}|j& %¡|_&|j&| |¡|j&|<qdS)NTrézYou are trying to merge on ú and z9 columns. If you wish to proceed you should use pd.concatÚignore)ÚinvalidzjYou are merging on int and float columns where the float values are not equal to their int representation.)Ú
stacklevelF)ZskipnaÚintegerz mixed-integerÚbooleanÚemptyÚstringÚunicodeÚmixedÚbytes)'ràr©r¨r§rr?r%rír.rr6Z#_categories_match_up_to_permutationr&r-Úkindr*r(r ÚerrstaterÙÚisnanryÚwarningsÚwarnÚ UserWarningrr Z infer_dtyper$r–r/rvr0rQrjrÜÚobjectr[rR)r¼rrräZ    lk_is_catZ    rk_is_catZ lk_is_objectZ rk_is_objectr¾Zcastedr ÚmatchZ inferred_leftZinferred_rightZ
bool_typesÚ string_typesÚtyprcrcrdrºòsÔÿ   
 
 
 
 
 
 
ÿ      û  ûÿ
ÿÿÿÿ ÿÿýý
 
 
ÿ
ÿ
        z(_MergeOperation._maybe_coerce_merge_keysz)tuple[DataFrame, DataFrame, JoinHow, str]cCs6dt ¡›}d}|jf|diŽ|jf|diŽ||fS)a
        Creates the configuration to dispatch the cross operation to inner join,
        e.g. adding a join column and resetting parameters. Join column is added
        to a new object, no inplace modification
 
        Parameters
        ----------
        left : DataFrame
        right : DataFrame
 
        Returns
        -------
            a tuple (left, right, how, cross_col) representing the adjusted
            DataFrames with cross_col, the merge operation set to inner and the column
            to join over.
        Z_cross_rHrª)ÚuuidÚuuid4Zassign)r¼rQrRr¿rSrcrcrdr·süz+_MergeOperation._create_cross_configurationc    Cs‚t |¡}t |¡}|jdkrP|jsD|jsD|dk    sD|dk    sD|jdk    rLtdƒ‚n|jdkr2|dkr2|dkr2|jr†|jr†d\}}n¨|jr–tdƒ‚n˜|jr¦tdƒ‚nˆ|jj}|j    j}| 
|¡}t |ƒdkrðtd|›d|›d    |j›d
|j›ƒ‚|j |d d j r|j |d d j s&td t|ƒ›ƒ‚|}}n"|jdk    r~|dk    sR|dk    rZtdƒ‚|jsj|jrrtdƒ‚|j}}nÖ|dk    rê|jr˜tdƒ‚|js²|dkr²tdƒ‚t |ƒ}|jrTt |ƒ|j    jjkrÞtdƒ‚dg|}nj|dk    rT|jrtdƒ‚|js|dkrtdƒ‚t |ƒ}|jrTt |ƒ|jjjkrJtdƒ‚dg|}|jdkrzt |ƒt |ƒkrztdƒ‚||fS)Nr­zMCan not pass on, right_on, left_on or set right_index=True or left_index=True)rcrcz&Must pass right_on or right_index=Truez$Must pass left_on or left_index=Truerz>No common columns to perform merge on. Merge options: left_on=z , right_on=z , left_index=z, right_index=rHrzData columns not unique: zSCan only pass argument "on" OR "left_on" and "right_on", not a combination of both.zYCan only pass argument "on" OR "left_index" and "right_index", not a combination of both.z:Can only pass argument "left_on" OR "left_index" not both.z&Must pass "right_on" OR "right_index".zDlen(left_on) must equal the number of levels in the index of "right"z<Can only pass argument "right_on" OR "right_index" not both.z$Must pass "left_on" OR "left_index".zDlen(right_on) must equal the number of levels in the index of "left"z%len(right_on) must equal len(left_on))r²r³rSrWrXrTrrQrjrRÚ intersectionrr Ú    is_uniqueÚreprr€rµr–)r¼rUrVZ    left_colsZ
right_colsZ common_colsÚnrcrcrdr¶¬sš
 
 
ÿþýüûÿ  
 
 
 
 ÿÿþ  ÿÿ 
ÿÿ 
ÿÿ
z'_MergeOperation._validate_left_right_onr—)r]r^cCs¼|jr|jjj}nt |j¡j}|jr2|jjj}nt |j    ¡j}|dkrr|sX|sXt
dƒ‚|sdt
dƒ‚|s¸t
dƒ‚nF|dkrˆ|s¸t
dƒ‚n0|dkrž|s¸t
dƒ‚n|d    kr¨nt d
|›d ƒ‚dS) N)Z
one_to_onez1:1zQMerge keys are not unique in either left or right dataset; not a one-to-one mergezAMerge keys are not unique in left dataset; not a one-to-one mergezBMerge keys are not unique in right dataset; not a one-to-one merge)Z one_to_manyz1:mzBMerge keys are not unique in left dataset; not a one-to-many merge)Z many_to_onezm:1zCMerge keys are not unique in right dataset; not a many-to-one merge)Z many_to_manyzm:mú"z" is not a valid argument. Valid arguments are:
- "1:1"
- "1:m"
- "m:1"
- "m:m"
- "one_to_one"
- "one_to_many"
- "many_to_one"
- "many_to_many") rWr¯r€r4r8Ú from_arraysr©rXr°r¨rr–)r¼r]Z left_uniqueZ right_uniquercrcrdr»sD  ÿÿÿÿÿ
ÿz_MergeOperation._validate) rHNNNrªFFTrIFN)T)rQ)Ú__name__Ú
__module__Ú __qualname__Ú__doc__rÎÚ__annotations__rÀrÉrarÒrrÔrÌrÏrÑrÐrrÍrr¹rºr·r¶r»rcrcrcrdr`zsd
ò*U8
+cBû"Zr`r¥rý)rYrSr^c s:tˆƒtˆƒkstdƒ‚tˆdƒ}tˆdƒ}|dkr^ˆdkrFtƒSˆsŠˆdkrŠt|dƒSn,|dkrŠˆdkrttƒSˆsŠˆdkrŠt|dƒS‡‡‡‡fd    d
„ttˆƒƒDƒ}t|Ž}d d
„|Dƒ\}    }
} t|    |
t| ƒˆƒ\} } t| | ˆˆd \} } }t     
|¡}ˆd krˆ|d<t j t j dd„t jdœˆ}|| | |f|ŽS)ac
 
    Parameters
    ----------
    left_keys : ndarray, Index, Series
    right_keys : ndarray, Index, Series
    sort : bool, default False
    how : {'inner', 'outer', 'left', 'right'}, default 'inner'
 
    Returns
    -------
    np.ndarray[np.intp]
        Indexer into the left_keys.
    np.ndarray[np.intp]
        Indexer into the right_keys.
    z/left_key and right_keys must be the same lengthr)rQrHr­)rRr‹T)rRrHr­)rQr‹Fc3s&|]}tˆ|ˆ|ˆˆdVqdS)rÿN)Ú_factorize_keys©rkr6©rSrrrYrcrdrnksÿz$get_join_indexers.<locals>.<genexpr>css|]}t|ƒVqdSrh©rwrçrcrcrdrnpsrÿrfrYc[stj|||f|Žddd…S)Nrè)ÚlibjoinÚleft_outer_join)rrÚcountÚkwargsrcrcrdr”sÿÿþz#get_join_indexers.<locals>.<lambda>)rHrQrRr‹)rrñÚ_get_empty_indexerÚ _get_no_sort_one_missing_indexerr~ràÚ_get_join_keysrxr>Úcpr[rBZ
inner_joinrCZfull_outer_join)rrrYrSrEZleft_nZright_nÚmappedÚzippedÚllabÚrlabÚshapeÚlkeyÚrkeyrDZ    join_funcrcr@rdrAsFÿþ     
 
þ
 
úù
rr8r7rz8tuple[list[Index], npt.NDArray[np.intp], list[Hashable]])rQrRrÁÚlindexerÚrindexerr^cCs¶dddœdd„}||ƒ}|j}|j}|j}    |D]|}
|
|jkrF|} |} n|} |} | j |
¡} | j| }| j| }| dkr||}ntj|| dd}||g}||g}|    |
g}    q.|||    fS)    aø
    *this is an internal non-public method*
 
    Returns the levels, labels and names of a multi-index to multi-index join.
    Depending on the type of join, this method restores the appropriate
    dropped levels of the joined multi-index.
    The method relies on lindexer, rindexer which hold the index positions of
    left and right, where a join was feasible
 
    Parameters
    ----------
    left : MultiIndex
        left index
    right : MultiIndex
        right index
    dropped_level_names : str array
        list of non-common level names
    join_index : Index
        the index of the join between the
        common levels of left and right
    lindexer : np.ndarray[np.intp]
        left indexer
    rindexer : np.ndarray[np.intp]
        right indexer
 
    Returns
    -------
    levels : list of Index
        levels of combined multiindexes
    labels : np.ndarray[np.intp]
        labels of combined multiindexes
    names : List[Hashable]
        names of combined multiindex levels
 
    r7r8)r€r^cSs(t|tƒr|Stj|jg|jgdSdS)N)râ)rvr8r8rõrä)r€rcrcrdÚ_convert_to_multiindex·s
z@restore_dropped_levels_multijoin.<locals>._convert_to_multiindexNrèrë)rrrâr€rör÷)rQrRZdropped_level_namesrÁrQrRrSZ join_levelsZ
join_codesr§Zdropped_level_nameÚidxr    Zname_idxZrestore_levelsrZ restore_codesrcrcrdÚ restore_dropped_levels_multijoin‹s*,
 
 
 
 
 
 rUc@sHeZdZdZddddddd    d    d
d d d ddœ dd„Zddddœdd„ZdS)rŽZ ordered_mergeNFrªrIr‹rKrLrMrrrPzJoinHow | Literal['asof']r«) rQrRrTrUrVrWrXrorZrŒrSr^c Cs,|
|_tj|||||||||| |    dd dS)NT)    rTrUrWrXrVrorSrZrY)rŒr`rÀ) r¼rQrRrTrUrVrWrXrorZrŒrSrcrcrdrÀçsôz_OrderedMerge.__init__TrNrDrÊc
Csž| ¡\}}}t|jj|jj|jƒ\}}|jdkrr|dkrBtdƒ‚tt    j
|ƒtt    j
|ƒ}}t   |¡}t   |¡}n|}|}|j ||||d}    | |    ||¡|    S)NZffillzleft_indexer cannot be Noner_)rÍrÄrQrÅrRrZrŒÚ    TypeErrorrr ZndarrayrBZ ffill_indexerrÉrÐ)
r¼r[rÁrÂrÃrÇrÈZleft_join_indexerZright_join_indexerr‰rcrcrdras2ÿ
 ÿ
 ÿz_OrderedMerge.get_result)    NNNFFrªrINr‹)T)r9r:r;rÎrÀrarcrcrcrdrŽäsô&rŽ)r cCsd|›d}tt|dƒS)NZ
asof_join_Z
_on_X_by_Y)ÚgetattrrB)r rärcrcrdÚ_asof_by_function#s rX)Úint64_tÚdoubler-r)rír^cCs t|ƒr dSt|ƒrdSdSdS)z2Upcast a dtype to 'int64_t', 'double', or 'object'rYrZr-N)r*r(©rírcrcrdÚ_get_cython_type_upcast/s
r\csleZdZdZdd    d    d
d
d
d d d d d ddd dddœdd„Z‡fdd„Zddœ‡fdd„ Zddœdd„Z‡ZS)r£Z
asof_mergeNFrªrITr¡ržrKrLrMrrrPzLiteral['asof']r—r«)rQrRrTrUrVrWrXrorZr[rŒrSrŸr r^cCsJ||_|    |_|
|_||_||_||_tj||||||||| || |d dS)N)    rTrUrVrWrXrorSrZrŒ)r‚r™ršr¢rŸr rŽrÀ)r¼rQrRrTrUrVrWrXr‚r™ršrorZr[rŒrSr¢rŸr rcrcrdrÀ<s(ôz_AsOfMerge.__init__csbtƒ ||¡\}}t|ƒdkr,|js,tdƒ‚t|ƒdkrF|jsFtdƒ‚|jrbt|jjt    ƒrbtdƒ‚|jr~t|j
jt    ƒr~tdƒ‚|j dk    r²|j dk    sœ|j dk    r¤tdƒ‚|j |_ |_ |j dkrÎ|j dk    rÎtdƒ‚|j dk    rê|j dkrêtdƒ‚|js8|d    }t|ƒr |j}n*||jjkr(|j |¡jn |jj |¡}n
|jjj}|js|d    }t|ƒrd|j}n*||j
jkr€|j
 |¡jn |j
j |¡}n
|j
jj}t|ƒs®t|ƒrÌtd
t|ƒ›d t|ƒ›d ƒ‚|j dk    r>t|j ƒsî|j g|_ t|j ƒs|j g|_ t|j ƒt|j ƒkr"td ƒ‚|j t|ƒ}|j t|ƒ}|jdkrZtd|j›ƒ‚||fS)Nrªzcan only asof on a key for leftz can only asof on a key for rightzleft can only have one indexzright can only have one indexz(Can only pass by OR left_by and right_byzmissing left_byzmissing right_byrzIncompatible merge dtype, rz$, both sides must have numeric dtypez(left_by and right_by must be same length)ržZforwardZnearestzdirection invalid: )Úsuperr¶rrWrrXrvrQr€r8rRr‚r™ršr"rírjrrîr.r5r+rwr )r¼rUrVZ    left_on_0Zlo_dtypeZ
right_on_0Zro_dtype©Ú    __class__rcrdr¶gsf
 
 
ÿ ý
 
 
ÿ ý
ÿ  
 
 z"_AsOfMerge._validate_left_right_onr rc    s¸tƒ ¡\}}}tt||ƒƒD]€\}\}}t|j|jƒst|jƒrrt|jƒrrd|›dt|jƒ›dt|jƒ›d}n$d|›dt|jƒ›dt|jƒ›d}t|ƒ‚q|j    dk    rŽ|j
rÂt t |j jƒ}n|d}d|j    ›dt|jƒ›}t|ƒrt|j    tjƒst|ƒ‚|j    td    ƒkrŽtd
ƒ‚npt|ƒrRt|j    ƒs<t|ƒ‚|j    d    krŽtd
ƒ‚n<t|ƒr†t|j    ƒspt|ƒ‚|j    d    krŽtd
ƒ‚ntd ƒ‚t|jƒs®d |j›}t|ƒ‚|||fS) Nzincompatible merge keys [z] rz), both sides category, but not equal onesz, must be the same typerèzincompatible tolerance z, must be compat with type rztolerance must be positivez'key must be integer, timestamp or floatz,allow_exact_matches must be boolean, passed )r]r¹ròràr&rír%r5rr¢rWrrrQr€r/rvÚdatetimeÚ    timedeltar    r*r)r(r,r#rŸ)    r¼r©r¨r§rÚrrr¾Últr^rcrdr¹¶sH
"ÿ"ÿ
 ÿ
 
 
 
 
 
 
ÿz_AsOfMerge._get_merge_keysrýcCsöddœdd„}|jr|jjjn|jd}|jr8|jjjn|jd}|j}t    |ƒj
s€d}t |ƒ  ¡rrt d|›dƒ‚t |›d    ƒ‚t    |ƒj
s¸d
}t |ƒ  ¡rªt d|›dƒ‚t |›d    ƒ‚t|ƒr |d k    røt|ƒ}|jjd kròt|ƒ}| |j¡}|j}| d ¡}| d ¡}|jd k    rÂ|jr6|jr6|j}|j}n|jdd…}|jdd…}t|ƒdkrr|d}    |d}
n||ƒ}    ||ƒ}
t|    jƒ} t| } | |    ƒ}| |
ƒ}t|jƒ} | |||||j|ƒSt|jƒ} | |j›dtf||d d |j|dƒSd S)rþú
np.ndarrayrcs`dd„‰‡fdd„|Dƒ}ttjdt|ƒ…ƒ}dd„|Dƒ}tt||ƒƒ}t tt|Žƒ|¡S)z4unlike np.transpose, this returns an array of tuplescSs.t|ƒs |St|ƒ}t|tƒr$|jSt |¡Srh)r'r?rvr=Ú_ndarrayr Zasarray©ÚobjrcrcrdÚ    injections 
 
z>_AsOfMerge._get_join_indexers.<locals>.flip.<locals>.injectioncsg|] }ˆ|ƒ‘qSrcrcrç©rgrcrdrssz?_AsOfMerge._get_join_indexers.<locals>.flip.<locals>.<listcomp>NcSsg|]
}|j‘qSrcr[rçrcrcrdrss)rwr#Úascii_lowercaserràr Úarray)ÚxsrÝZdtypesZlabeled_dtypesrcrhrdÚflips z+_AsOfMerge._get_join_indexers.<locals>.fliprèrQz"Merge keys contain null values on z sidez keys must be sortedrRN)ÚmÚMÚi8rrªZ_tF)rWrQr€rõr©rXrRr¨r¢r7Zis_monotonic_increasingr3rôr–r/r    rír'r>Zas_unitÚunitÚ_valueÚviewr™rr\Ú _type_castersrXr rŸr-)r¼rlZ left_valuesZ right_valuesr¢ZsideZlvsZleft_by_valuesZright_by_valuesZlbvZrbvZby_typeZby_type_casterÚfuncrcrcrdrÿsvÿÿ
 
 
 
 
 
 
 
ú
 
ùz_AsOfMerge._get_join_indexers)NNNFFNNNrªrITNr¡NTrž)    r9r:r;rÎrÀr¶r¹rÚ __classcell__rcrcr^rdr£9s*í,+ OIr£)r€rYr^cs$‡‡‡fdd„tˆjƒDƒ}t|Ž}dd„|Dƒ\}}}ˆrRtttj|ˆjƒƒ}ndd„}tt|ˆjƒƒ}tˆƒD]t\}    }
ˆj|    dk} |      ¡rr|
||    ||    dk} | j
dksÂ| d| dksÒ||    d7<||    d||    | <qrt ||t |ƒˆƒ\} }t | |ˆd    \} }}tj| ||ˆd    S)
Nc3s&|]}tˆj|ˆ|ˆdVqdS)rgN)r>rr?©r€Ú    join_keysrYrcrdrnŠsÿz*_get_multiindex_indexer.<locals>.<genexpr>css|]}t|ƒVqdSrhrArçrcrcrdrnscSs|jddddS)NroFT©Zsubokr[)rÙ)Úarcrcrdr”“r•z)_get_multiindex_indexer.<locals>.<lambda>rèrªrrg)r~rµràrwÚmapr rzrròrôÚsizerHrxr>rBrC)rwr€rYrJrKZrcodesZlcodesrNZi8copyrÚÚjoin_keyr ryrOrPrDrcrvrdÚ_get_multiindex_indexer†s&þr}cCs(t||j|d\}}}tj||||dS)Nrg)r>rõrBrC)r|r€rYrårærDrcrcrdÚ_get_single_indexer«sr~rcCs tjgtjdtjgtjdfS)zReturn empty join indexers.r[)r rjÚintprcrcrcrdrF³sþrFÚint)r6Ú left_missingr^cCs6tj|tjd}tj|dtjd}|r.||fS||fS)aÏ
    Return join indexers where all of one side is selected without sorting
    and none of the other side is selected.
 
    Parameters
    ----------
    n : int
        Length of indexers to create.
    left_missing : bool
        If True, the left indexer will contain only -1's.
        If False, the right indexer will contain only -1's.
 
    Returns
    -------
    np.ndarray[np.intp]
        Left indexer
    np.ndarray[np.intp]
        Right indexer
    r[rè)rNrìrí)r ZarangerÚfull)r6rrTZ idx_missingrcrcrdrG»s
rGz?tuple[Index, npt.NDArray[np.intp] | None, npt.NDArray[np.intp]])rrrYr^cCsŒt|ƒdkr@t|tƒr$t|ƒ|jks,tdƒ‚t|||d\}}n|d}t|||d\}}|snt|ƒt|ƒkr‚| |¡}|||fS|d|fS)NrªzŒIf more than one join key is given then 'right_ax' must be a MultiIndex and the number of join keys must be the number of levels in right_axrgr)rrvr8rµrñr}r~rz)rrrwrYrÂrÃZjkeyrÁrcrcrdrØs& ÿ ÿÿÿ 
 
rrz6tuple[npt.NDArray[np.intp], npt.NDArray[np.intp], int])rrrYrSr^cCs¶t|ddd}t|ddd}t|jtƒrNt|jtƒrNtd|ƒj}td|ƒj}n°t|jƒr¬t|jƒr¬t|j|jƒr¬t|tƒs~t    ‚t|tƒsŒt    ‚| 
|¡}t |j ƒ}t |j ƒ}nRt|t ƒrþt|j|jƒrþt|tƒsþt|jtƒræt|jjƒsþ| ¡\}}| ¡\}}t||ƒ\}}}|tt|ƒt|ƒƒƒ}t|tƒrft|tƒs@t    ‚|j|j|jd}|j|j|jd}nrt|tƒrÄt|tƒs‚t    ‚|j|jd|jjd| ¡d}|j|jd|jjd| ¡d}n| |¡}| |¡}|jt tj¡ksöt    |jƒ‚|jt tj¡kst    |jƒ‚| ¡}    |r<|j  ¡}
t!|
||ƒ\}}|dk} |  "¡} |dk} |  "¡}| sh|r˜| r|t #|| |    ¡|rt #|| |    ¡|    d7}    |dkr¬|||    fS|||    fS)    u?
    Encode left and right keys as enumerated types.
 
    This is used to get the join indexers to be used when merging DataFrames.
 
    Parameters
    ----------
    lk : array-like
        Left key.
    rk : array-like
        Right key.
    sort : bool, defaults to True
        If True, the encoding is done such that the unique elements in the
        keys are sorted.
    how : {‘left’, â€˜right’, â€˜outer’, â€˜inner’}, default â€˜inner’
        Type of merge.
 
    Returns
    -------
    np.ndarray[np.intp]
        Left (resp. right if called with `key='right'`) labels, as enumerated type.
    np.ndarray[np.intp]
        Right (resp. left if called with `key='right'`) labels, as enumerated type.
    int
        Number of unique elements in union of left and right labels.
 
    See Also
    --------
    merge : Merge DataFrame or named Series objects
        with a database-style join.
    algorithms.factorize : Encode the object as an enumerated type
        or categorical variable.
 
    Examples
    --------
    >>> lk = np.array(["a", "c", "b"])
    >>> rk = np.array(["a", "c"])
 
    Here, the unique values are `'a', 'b', 'c'`. With the default
    `sort=True`, the encoding will be `{0: 'a', 1: 'b', 2: 'c'}`:
 
    >>> pd.core.reshape.merge._factorize_keys(lk, rk)
    (array([0, 2, 1]), array([0, 2]), 3)
 
    With the `sort=False`, the encoding will correspond to the order
    in which the unique elements first appear: `{0: 'a', 1: 'c', 2: 'b'}`:
 
    >>> pd.core.reshape.merge._factorize_keys(lk, rk, sort=False)
    (array([0, 1, 2]), array([0, 1]), 3)
    T)rêZ extract_rangerF)r rª)Zna_valuerírèrR)$r?rvrír0rrdr%r&r6rñZ_encode_with_my_categoriesr rr<r;r5r-Ú numpy_dtypeZ_values_for_factorizeÚ#_convert_arrays_and_get_rizer_klassÚmaxrZ    factorizeÚ_dataZ_maskr:Zto_numpyr3r rZ    get_countÚuniquesZto_arrayÚ _sort_labelsrôZputmask)rrrYrSrœÚklassZrizerrLrMrDr‡ZlmaskZlanyZrmaskZranyrcrcrdr>ösz9 ÿþ ý
 
 
 
þ
ý    ÿÿ
 
 
 
 
r>z:tuple[type[libhashtable.Factorizer], ArrayLike, ArrayLike])rrr^cCsút|jƒrÚt||ƒs˜t|j|jgƒ}t|tƒr„| ¡}t|tƒsR|j||dd}n
|     |¡}t|tƒsx|j||dd}q˜|     |¡}n|     |¡}|     |¡}t|t
ƒr°t |jj }qðt|jt ƒrÌt |jjj }qðt |jj }ntj}t|ƒ}t|ƒ}|||fS)NF)rír[)r-rír&rrvrZconstruct_array_typer<Z_from_sequencerÙr;Ú _factorizersr´r5rƒÚ libhashtableÚObjectFactorizerr!)rrríÚclsr‰rcrcrdr„‡    s,
 
 
 
 
 
 
 
 
 r„rc)r‡rQrRr^c    CsLt|ƒ}t ||g¡}tj||dd\}}|d|…||d…}}||fS)NT)Zuse_na_sentinel)rr Z concatenateröZ    safe_sort)    r‡rQrRZllengthrÝrœZ
new_labelsZnew_leftZ    new_rightrcrcrdrˆ¬    s
rˆz%list[npt.NDArray[np.int64 | np.intp]]rz3tuple[npt.NDArray[np.int64], npt.NDArray[np.int64]])rLrMrNrYr^c
 
s(t‡fdd„ttˆƒddƒDƒƒ}tjˆd|…dd}||djdddd    }||djdddd    }td|ƒD]H}tjd
d |ˆ|}W5QRX||||7}||||7}qr|tˆƒkrÐ||fSt|||d \}}}    |g||d…}|g||d…}|    fˆ|d…‰t||ˆ|ƒS) Nc3s"|]}tˆd|…ƒs|VqdSrhrB)rkr©rNrcrdrn¿    sþz!_get_join_keys.<locals>.<genexpr>rrèrªror[Frxr)Údividerg)    Únextr~rr ÚprodrÙr(r>rH)
rLrMrNrYZnlevZstriderOrPrÚrDrcrŽrdrH¸    s$ þ rHcCs t|tƒrt|tƒsdS||kS)NT)rvr—)rûrürcrcrdróÝ    srócCs|dk    otj|ŽSrh)r²Z any_not_nonerrcrcrdrã    sr)rfr^cCsJt|tƒr|St|tƒr2|jdkr*tdƒ‚| ¡Stdt|ƒ›dƒ‚dS)Nz$Cannot merge a Series without a namez.Can only merge Series or DataFrame objects, a z  was passed)rvr1r2rär–Zto_framerVr´rercrcrdr®ç    s
 
 
ÿr®ztuple[Index, Index])rQrRrZr^c s
t|ddrt|tƒr*tdt|ƒ›dƒ‚| |¡‰tˆƒdkrH||fS|\}}|sf|sftdˆ›ƒ‚‡fdd„}t||d    }t||d    }|     |¡}|     |¡}    g}
|j
sÂ||  ¡|  ¡@  ¡}
|    j
sè|
  |    |      ¡|  ¡@  ¡¡|
rtd
t|
ƒ›d ƒ‚||    fS) z¶
    Suffixes type validation.
 
    If two indices overlap, add suffixes to overlapping entries.
 
    If corresponding suffix is empty, the entry is simply converted to string.
 
    F)Z
allow_setszPassing 'suffixes' as a z:, is not supported. Provide 'suffixes' as a tuple instead.rz)columns overlap but no suffix specified: cs |ˆkr|dk    r|›|›S|S)a?
        Rename the left and right indices.
 
        If there is overlap, and suffix is not None, add
        suffix, otherwise, leave it as-is.
 
        Parameters
        ----------
        x : original column name
        suffix : str or None
 
        Returns
        -------
        x : renamed column name
        Nrc)rÚsuffix©Z    to_renamercrdÚrenamer
s z+_items_overlap_with_suffix.<locals>.renamer)r’z1Passing 'suffixes' which cause duplicate columns z is not allowed.)r+rvÚdictrVr´r3rr–rZ_transform_indexr4Z
duplicatedr}Úextendrrp) rQrRrZZlsuffixZrsuffixr”ZlrenamerZrrenamerrÇrÈZdupsrcr“rdrÄô    s2 ÿ
 
 
 ÿrÄ) rHNNNFFFrINFN)NNNNNNrIr‹) NNNFFNNNrINTrž)FrH)F)F)TrH)£r<Ú
__future__rr[rIr`Ú    functoolsrr#Útypingrrrrrr1r*Únumpyr Z pandas._libsr    r
r‹r rBr Zpandas._libs.libr Zpandas._typingrrrrrrrrrrZ pandas.errorsrZpandas.util._decoratorsrrrZpandas.util._exceptionsrZpandas.core.dtypes.baserZpandas.core.dtypes.castrZpandas.core.dtypes.commonrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.r/Zpandas.core.dtypes.dtypesr0Zpandas.core.dtypes.genericr1r2Zpandas.core.dtypes.missingr3r4rÆr5r6r7r8r9Zpandas.core.algorithmsÚcoreZ
algorithmsröZpandas.core.arraysr:r;r<Zpandas.core.arrays._mixinsr=Zpandas.core.commonÚcommonr²Zpandas.core.constructionr>r?Zpandas.core.framer@Zpandas.core.indexes.apirAZpandas.core.sortingrCrDZ pandas.corerErFÚint64ZInt64FactorizerZlonglongÚint32ZInt32FactorizerÚint16ZInt16Factorizerr×ZInt8FactorizerZuint64ZUInt64FactorizerZuint32ZUInt32FactorizerZuint16ZUInt16FactorizerZuint8ZUInt8FactorizerZbool_Úfloat64ZFloat64FactorizerÚfloat32ZFloat32FactorizerZ    complex64ZComplex64FactorizerZ
complex128ZComplex128FactorizerZobject_rŒrŠrerŠrr¤r`rrUrŽrXrsr\r£r}r~rFrGrr>r„rˆrHrórr®rÄrcrcrcrdÚ<module>s"   0    L        ñ
ó. :ö ò$QüJY?ý
O&ÿÿ!ü% %