test_merge.py 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781
  1. from datetime import (
  2. date,
  3. datetime,
  4. timedelta,
  5. )
  6. import re
  7. import numpy as np
  8. import pytest
  9. from pandas.core.dtypes.common import (
  10. is_categorical_dtype,
  11. is_object_dtype,
  12. )
  13. from pandas.core.dtypes.dtypes import CategoricalDtype
  14. import pandas as pd
  15. from pandas import (
  16. Categorical,
  17. CategoricalIndex,
  18. DataFrame,
  19. DatetimeIndex,
  20. Index,
  21. IntervalIndex,
  22. MultiIndex,
  23. PeriodIndex,
  24. RangeIndex,
  25. Series,
  26. TimedeltaIndex,
  27. )
  28. import pandas._testing as tm
  29. from pandas.api.types import CategoricalDtype as CDT
  30. from pandas.core.reshape.concat import concat
  31. from pandas.core.reshape.merge import (
  32. MergeError,
  33. merge,
  34. )
  35. def get_test_data(ngroups=8, n=50):
  36. unique_groups = list(range(ngroups))
  37. arr = np.asarray(np.tile(unique_groups, n // ngroups))
  38. if len(arr) < n:
  39. arr = np.asarray(list(arr) + unique_groups[: n - len(arr)])
  40. np.random.shuffle(arr)
  41. return arr
  42. def get_series():
  43. return [
  44. Series([1], dtype="int64"),
  45. Series([1], dtype="Int64"),
  46. Series([1.23]),
  47. Series(["foo"]),
  48. Series([True]),
  49. Series([pd.Timestamp("2018-01-01")]),
  50. Series([pd.Timestamp("2018-01-01", tz="US/Eastern")]),
  51. ]
  52. def get_series_na():
  53. return [
  54. Series([np.nan], dtype="Int64"),
  55. Series([np.nan], dtype="float"),
  56. Series([np.nan], dtype="object"),
  57. Series([pd.NaT]),
  58. ]
  59. @pytest.fixture(params=get_series(), ids=lambda x: x.dtype.name)
  60. def series_of_dtype(request):
  61. """
  62. A parametrized fixture returning a variety of Series of different
  63. dtypes
  64. """
  65. return request.param
  66. @pytest.fixture(params=get_series(), ids=lambda x: x.dtype.name)
  67. def series_of_dtype2(request):
  68. """
  69. A duplicate of the series_of_dtype fixture, so that it can be used
  70. twice by a single function
  71. """
  72. return request.param
  73. @pytest.fixture(params=get_series_na(), ids=lambda x: x.dtype.name)
  74. def series_of_dtype_all_na(request):
  75. """
  76. A parametrized fixture returning a variety of Series with all NA
  77. values
  78. """
  79. return request.param
  80. @pytest.fixture
  81. def dfs_for_indicator():
  82. df1 = DataFrame({"col1": [0, 1], "col_conflict": [1, 2], "col_left": ["a", "b"]})
  83. df2 = DataFrame(
  84. {
  85. "col1": [1, 2, 3, 4, 5],
  86. "col_conflict": [1, 2, 3, 4, 5],
  87. "col_right": [2, 2, 2, 2, 2],
  88. }
  89. )
  90. return df1, df2
  91. class TestMerge:
  92. @pytest.fixture
  93. def df(self):
  94. df = DataFrame(
  95. {
  96. "key1": get_test_data(),
  97. "key2": get_test_data(),
  98. "data1": np.random.randn(50),
  99. "data2": np.random.randn(50),
  100. }
  101. )
  102. # exclude a couple keys for fun
  103. df = df[df["key2"] > 1]
  104. return df
  105. @pytest.fixture
  106. def df2(self):
  107. return DataFrame(
  108. {
  109. "key1": get_test_data(n=10),
  110. "key2": get_test_data(ngroups=4, n=10),
  111. "value": np.random.randn(10),
  112. }
  113. )
  114. @pytest.fixture
  115. def left(self):
  116. return DataFrame(
  117. {"key": ["a", "b", "c", "d", "e", "e", "a"], "v1": np.random.randn(7)}
  118. )
  119. @pytest.fixture
  120. def right(self):
  121. return DataFrame({"v2": np.random.randn(4)}, index=["d", "b", "c", "a"])
  122. def test_merge_inner_join_empty(self):
  123. # GH 15328
  124. df_empty = DataFrame()
  125. df_a = DataFrame({"a": [1, 2]}, index=[0, 1], dtype="int64")
  126. result = merge(df_empty, df_a, left_index=True, right_index=True)
  127. expected = DataFrame({"a": []}, dtype="int64")
  128. tm.assert_frame_equal(result, expected)
  129. def test_merge_common(self, df, df2):
  130. joined = merge(df, df2)
  131. exp = merge(df, df2, on=["key1", "key2"])
  132. tm.assert_frame_equal(joined, exp)
  133. def test_merge_non_string_columns(self):
  134. # https://github.com/pandas-dev/pandas/issues/17962
  135. # Checks that method runs for non string column names
  136. left = DataFrame(
  137. {0: [1, 0, 1, 0], 1: [0, 1, 0, 0], 2: [0, 0, 2, 0], 3: [1, 0, 0, 3]}
  138. )
  139. right = left.astype(float)
  140. expected = left
  141. result = merge(left, right)
  142. tm.assert_frame_equal(expected, result)
  143. def test_merge_index_as_on_arg(self, df, df2):
  144. # GH14355
  145. left = df.set_index("key1")
  146. right = df2.set_index("key1")
  147. result = merge(left, right, on="key1")
  148. expected = merge(df, df2, on="key1").set_index("key1")
  149. tm.assert_frame_equal(result, expected)
  150. def test_merge_index_singlekey_right_vs_left(self):
  151. left = DataFrame(
  152. {"key": ["a", "b", "c", "d", "e", "e", "a"], "v1": np.random.randn(7)}
  153. )
  154. right = DataFrame({"v2": np.random.randn(4)}, index=["d", "b", "c", "a"])
  155. merged1 = merge(
  156. left, right, left_on="key", right_index=True, how="left", sort=False
  157. )
  158. merged2 = merge(
  159. right, left, right_on="key", left_index=True, how="right", sort=False
  160. )
  161. tm.assert_frame_equal(merged1, merged2.loc[:, merged1.columns])
  162. merged1 = merge(
  163. left, right, left_on="key", right_index=True, how="left", sort=True
  164. )
  165. merged2 = merge(
  166. right, left, right_on="key", left_index=True, how="right", sort=True
  167. )
  168. tm.assert_frame_equal(merged1, merged2.loc[:, merged1.columns])
  169. def test_merge_index_singlekey_inner(self):
  170. left = DataFrame(
  171. {"key": ["a", "b", "c", "d", "e", "e", "a"], "v1": np.random.randn(7)}
  172. )
  173. right = DataFrame({"v2": np.random.randn(4)}, index=["d", "b", "c", "a"])
  174. # inner join
  175. result = merge(left, right, left_on="key", right_index=True, how="inner")
  176. expected = left.join(right, on="key").loc[result.index]
  177. tm.assert_frame_equal(result, expected)
  178. result = merge(right, left, right_on="key", left_index=True, how="inner")
  179. expected = left.join(right, on="key").loc[result.index]
  180. tm.assert_frame_equal(result, expected.loc[:, result.columns])
  181. def test_merge_misspecified(self, df, df2, left, right):
  182. msg = "Must pass right_on or right_index=True"
  183. with pytest.raises(pd.errors.MergeError, match=msg):
  184. merge(left, right, left_index=True)
  185. msg = "Must pass left_on or left_index=True"
  186. with pytest.raises(pd.errors.MergeError, match=msg):
  187. merge(left, right, right_index=True)
  188. msg = (
  189. 'Can only pass argument "on" OR "left_on" and "right_on", not '
  190. "a combination of both"
  191. )
  192. with pytest.raises(pd.errors.MergeError, match=msg):
  193. merge(left, left, left_on="key", on="key")
  194. msg = r"len\(right_on\) must equal len\(left_on\)"
  195. with pytest.raises(ValueError, match=msg):
  196. merge(df, df2, left_on=["key1"], right_on=["key1", "key2"])
  197. def test_index_and_on_parameters_confusion(self, df, df2):
  198. msg = "right_index parameter must be of type bool, not <class 'list'>"
  199. with pytest.raises(ValueError, match=msg):
  200. merge(
  201. df,
  202. df2,
  203. how="left",
  204. left_index=False,
  205. right_index=["key1", "key2"],
  206. )
  207. msg = "left_index parameter must be of type bool, not <class 'list'>"
  208. with pytest.raises(ValueError, match=msg):
  209. merge(
  210. df,
  211. df2,
  212. how="left",
  213. left_index=["key1", "key2"],
  214. right_index=False,
  215. )
  216. with pytest.raises(ValueError, match=msg):
  217. merge(
  218. df,
  219. df2,
  220. how="left",
  221. left_index=["key1", "key2"],
  222. right_index=["key1", "key2"],
  223. )
  224. def test_merge_overlap(self, left):
  225. merged = merge(left, left, on="key")
  226. exp_len = (left["key"].value_counts() ** 2).sum()
  227. assert len(merged) == exp_len
  228. assert "v1_x" in merged
  229. assert "v1_y" in merged
  230. def test_merge_different_column_key_names(self):
  231. left = DataFrame({"lkey": ["foo", "bar", "baz", "foo"], "value": [1, 2, 3, 4]})
  232. right = DataFrame({"rkey": ["foo", "bar", "qux", "foo"], "value": [5, 6, 7, 8]})
  233. merged = left.merge(
  234. right, left_on="lkey", right_on="rkey", how="outer", sort=True
  235. )
  236. exp = Series(["bar", "baz", "foo", "foo", "foo", "foo", np.nan], name="lkey")
  237. tm.assert_series_equal(merged["lkey"], exp)
  238. exp = Series(["bar", np.nan, "foo", "foo", "foo", "foo", "qux"], name="rkey")
  239. tm.assert_series_equal(merged["rkey"], exp)
  240. exp = Series([2, 3, 1, 1, 4, 4, np.nan], name="value_x")
  241. tm.assert_series_equal(merged["value_x"], exp)
  242. exp = Series([6, np.nan, 5, 8, 5, 8, 7], name="value_y")
  243. tm.assert_series_equal(merged["value_y"], exp)
  244. def test_merge_copy(self):
  245. left = DataFrame({"a": 0, "b": 1}, index=range(10))
  246. right = DataFrame({"c": "foo", "d": "bar"}, index=range(10))
  247. merged = merge(left, right, left_index=True, right_index=True, copy=True)
  248. merged["a"] = 6
  249. assert (left["a"] == 0).all()
  250. merged["d"] = "peekaboo"
  251. assert (right["d"] == "bar").all()
  252. def test_merge_nocopy(self, using_array_manager):
  253. left = DataFrame({"a": 0, "b": 1}, index=range(10))
  254. right = DataFrame({"c": "foo", "d": "bar"}, index=range(10))
  255. merged = merge(left, right, left_index=True, right_index=True, copy=False)
  256. assert np.shares_memory(merged["a"]._values, left["a"]._values)
  257. assert np.shares_memory(merged["d"]._values, right["d"]._values)
  258. def test_intelligently_handle_join_key(self):
  259. # #733, be a bit more 1337 about not returning unconsolidated DataFrame
  260. left = DataFrame(
  261. {"key": [1, 1, 2, 2, 3], "value": list(range(5))}, columns=["value", "key"]
  262. )
  263. right = DataFrame({"key": [1, 1, 2, 3, 4, 5], "rvalue": list(range(6))})
  264. joined = merge(left, right, on="key", how="outer")
  265. expected = DataFrame(
  266. {
  267. "key": [1, 1, 1, 1, 2, 2, 3, 4, 5],
  268. "value": np.array([0, 0, 1, 1, 2, 3, 4, np.nan, np.nan]),
  269. "rvalue": [0, 1, 0, 1, 2, 2, 3, 4, 5],
  270. },
  271. columns=["value", "key", "rvalue"],
  272. )
  273. tm.assert_frame_equal(joined, expected)
  274. def test_merge_join_key_dtype_cast(self):
  275. # #8596
  276. df1 = DataFrame({"key": [1], "v1": [10]})
  277. df2 = DataFrame({"key": [2], "v1": [20]})
  278. df = merge(df1, df2, how="outer")
  279. assert df["key"].dtype == "int64"
  280. df1 = DataFrame({"key": [True], "v1": [1]})
  281. df2 = DataFrame({"key": [False], "v1": [0]})
  282. df = merge(df1, df2, how="outer")
  283. # GH13169
  284. # GH#40073
  285. assert df["key"].dtype == "bool"
  286. df1 = DataFrame({"val": [1]})
  287. df2 = DataFrame({"val": [2]})
  288. lkey = np.array([1])
  289. rkey = np.array([2])
  290. df = merge(df1, df2, left_on=lkey, right_on=rkey, how="outer")
  291. assert df["key_0"].dtype == np.int_
  292. def test_handle_join_key_pass_array(self):
  293. left = DataFrame(
  294. {"key": [1, 1, 2, 2, 3], "value": np.arange(5)},
  295. columns=["value", "key"],
  296. dtype="int64",
  297. )
  298. right = DataFrame({"rvalue": np.arange(6)}, dtype="int64")
  299. key = np.array([1, 1, 2, 3, 4, 5], dtype="int64")
  300. merged = merge(left, right, left_on="key", right_on=key, how="outer")
  301. merged2 = merge(right, left, left_on=key, right_on="key", how="outer")
  302. tm.assert_series_equal(merged["key"], merged2["key"])
  303. assert merged["key"].notna().all()
  304. assert merged2["key"].notna().all()
  305. left = DataFrame({"value": np.arange(5)}, columns=["value"])
  306. right = DataFrame({"rvalue": np.arange(6)})
  307. lkey = np.array([1, 1, 2, 2, 3])
  308. rkey = np.array([1, 1, 2, 3, 4, 5])
  309. merged = merge(left, right, left_on=lkey, right_on=rkey, how="outer")
  310. expected = Series([1, 1, 1, 1, 2, 2, 3, 4, 5], dtype=np.int_, name="key_0")
  311. tm.assert_series_equal(merged["key_0"], expected)
  312. left = DataFrame({"value": np.arange(3)})
  313. right = DataFrame({"rvalue": np.arange(6)})
  314. key = np.array([0, 1, 1, 2, 2, 3], dtype=np.int64)
  315. merged = merge(left, right, left_index=True, right_on=key, how="outer")
  316. tm.assert_series_equal(merged["key_0"], Series(key, name="key_0"))
  317. def test_no_overlap_more_informative_error(self):
  318. dt = datetime.now()
  319. df1 = DataFrame({"x": ["a"]}, index=[dt])
  320. df2 = DataFrame({"y": ["b", "c"]}, index=[dt, dt])
  321. msg = (
  322. "No common columns to perform merge on. "
  323. f"Merge options: left_on={None}, right_on={None}, "
  324. f"left_index={False}, right_index={False}"
  325. )
  326. with pytest.raises(MergeError, match=msg):
  327. merge(df1, df2)
  328. def test_merge_non_unique_indexes(self):
  329. dt = datetime(2012, 5, 1)
  330. dt2 = datetime(2012, 5, 2)
  331. dt3 = datetime(2012, 5, 3)
  332. dt4 = datetime(2012, 5, 4)
  333. df1 = DataFrame({"x": ["a"]}, index=[dt])
  334. df2 = DataFrame({"y": ["b", "c"]}, index=[dt, dt])
  335. _check_merge(df1, df2)
  336. # Not monotonic
  337. df1 = DataFrame({"x": ["a", "b", "q"]}, index=[dt2, dt, dt4])
  338. df2 = DataFrame(
  339. {"y": ["c", "d", "e", "f", "g", "h"]}, index=[dt3, dt3, dt2, dt2, dt, dt]
  340. )
  341. _check_merge(df1, df2)
  342. df1 = DataFrame({"x": ["a", "b"]}, index=[dt, dt])
  343. df2 = DataFrame({"y": ["c", "d"]}, index=[dt, dt])
  344. _check_merge(df1, df2)
  345. def test_merge_non_unique_index_many_to_many(self):
  346. dt = datetime(2012, 5, 1)
  347. dt2 = datetime(2012, 5, 2)
  348. dt3 = datetime(2012, 5, 3)
  349. df1 = DataFrame({"x": ["a", "b", "c", "d"]}, index=[dt2, dt2, dt, dt])
  350. df2 = DataFrame(
  351. {"y": ["e", "f", "g", " h", "i"]}, index=[dt2, dt2, dt3, dt, dt]
  352. )
  353. _check_merge(df1, df2)
  354. def test_left_merge_empty_dataframe(self):
  355. left = DataFrame({"key": [1], "value": [2]})
  356. right = DataFrame({"key": []})
  357. result = merge(left, right, on="key", how="left")
  358. tm.assert_frame_equal(result, left)
  359. result = merge(right, left, on="key", how="right")
  360. tm.assert_frame_equal(result, left)
  361. @pytest.mark.parametrize(
  362. "kwarg",
  363. [
  364. {"left_index": True, "right_index": True},
  365. {"left_index": True, "right_on": "x"},
  366. {"left_on": "a", "right_index": True},
  367. {"left_on": "a", "right_on": "x"},
  368. ],
  369. )
  370. def test_merge_left_empty_right_empty(self, join_type, kwarg):
  371. # GH 10824
  372. left = DataFrame(columns=["a", "b", "c"])
  373. right = DataFrame(columns=["x", "y", "z"])
  374. exp_in = DataFrame(columns=["a", "b", "c", "x", "y", "z"], dtype=object)
  375. result = merge(left, right, how=join_type, **kwarg)
  376. tm.assert_frame_equal(result, exp_in)
  377. def test_merge_left_empty_right_notempty(self):
  378. # GH 10824
  379. left = DataFrame(columns=["a", "b", "c"])
  380. right = DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=["x", "y", "z"])
  381. exp_out = DataFrame(
  382. {
  383. "a": np.array([np.nan] * 3, dtype=object),
  384. "b": np.array([np.nan] * 3, dtype=object),
  385. "c": np.array([np.nan] * 3, dtype=object),
  386. "x": [1, 4, 7],
  387. "y": [2, 5, 8],
  388. "z": [3, 6, 9],
  389. },
  390. columns=["a", "b", "c", "x", "y", "z"],
  391. )
  392. exp_in = exp_out[0:0] # make empty DataFrame keeping dtype
  393. def check1(exp, kwarg):
  394. result = merge(left, right, how="inner", **kwarg)
  395. tm.assert_frame_equal(result, exp)
  396. result = merge(left, right, how="left", **kwarg)
  397. tm.assert_frame_equal(result, exp)
  398. def check2(exp, kwarg):
  399. result = merge(left, right, how="right", **kwarg)
  400. tm.assert_frame_equal(result, exp)
  401. result = merge(left, right, how="outer", **kwarg)
  402. tm.assert_frame_equal(result, exp)
  403. for kwarg in [
  404. {"left_index": True, "right_index": True},
  405. {"left_index": True, "right_on": "x"},
  406. ]:
  407. check1(exp_in, kwarg)
  408. check2(exp_out, kwarg)
  409. kwarg = {"left_on": "a", "right_index": True}
  410. check1(exp_in, kwarg)
  411. exp_out["a"] = [0, 1, 2]
  412. check2(exp_out, kwarg)
  413. kwarg = {"left_on": "a", "right_on": "x"}
  414. check1(exp_in, kwarg)
  415. exp_out["a"] = np.array([np.nan] * 3, dtype=object)
  416. check2(exp_out, kwarg)
  417. def test_merge_left_notempty_right_empty(self):
  418. # GH 10824
  419. left = DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=["a", "b", "c"])
  420. right = DataFrame(columns=["x", "y", "z"])
  421. exp_out = DataFrame(
  422. {
  423. "a": [1, 4, 7],
  424. "b": [2, 5, 8],
  425. "c": [3, 6, 9],
  426. "x": np.array([np.nan] * 3, dtype=object),
  427. "y": np.array([np.nan] * 3, dtype=object),
  428. "z": np.array([np.nan] * 3, dtype=object),
  429. },
  430. columns=["a", "b", "c", "x", "y", "z"],
  431. )
  432. exp_in = exp_out[0:0] # make empty DataFrame keeping dtype
  433. # result will have object dtype
  434. exp_in.index = exp_in.index.astype(object)
  435. def check1(exp, kwarg):
  436. result = merge(left, right, how="inner", **kwarg)
  437. tm.assert_frame_equal(result, exp)
  438. result = merge(left, right, how="right", **kwarg)
  439. tm.assert_frame_equal(result, exp)
  440. def check2(exp, kwarg):
  441. result = merge(left, right, how="left", **kwarg)
  442. tm.assert_frame_equal(result, exp)
  443. result = merge(left, right, how="outer", **kwarg)
  444. tm.assert_frame_equal(result, exp)
  445. # TODO: should the next loop be un-indented? doing so breaks this test
  446. for kwarg in [
  447. {"left_index": True, "right_index": True},
  448. {"left_index": True, "right_on": "x"},
  449. {"left_on": "a", "right_index": True},
  450. {"left_on": "a", "right_on": "x"},
  451. ]:
  452. check1(exp_in, kwarg)
  453. check2(exp_out, kwarg)
  454. def test_merge_empty_frame(self, series_of_dtype, series_of_dtype2):
  455. # GH 25183
  456. df = DataFrame(
  457. {"key": series_of_dtype, "value": series_of_dtype2},
  458. columns=["key", "value"],
  459. )
  460. df_empty = df[:0]
  461. expected = DataFrame(
  462. {
  463. "value_x": Series(dtype=df.dtypes["value"]),
  464. "key": Series(dtype=df.dtypes["key"]),
  465. "value_y": Series(dtype=df.dtypes["value"]),
  466. },
  467. columns=["value_x", "key", "value_y"],
  468. )
  469. actual = df_empty.merge(df, on="key")
  470. tm.assert_frame_equal(actual, expected)
  471. def test_merge_all_na_column(self, series_of_dtype, series_of_dtype_all_na):
  472. # GH 25183
  473. df_left = DataFrame(
  474. {"key": series_of_dtype, "value": series_of_dtype_all_na},
  475. columns=["key", "value"],
  476. )
  477. df_right = DataFrame(
  478. {"key": series_of_dtype, "value": series_of_dtype_all_na},
  479. columns=["key", "value"],
  480. )
  481. expected = DataFrame(
  482. {
  483. "key": series_of_dtype,
  484. "value_x": series_of_dtype_all_na,
  485. "value_y": series_of_dtype_all_na,
  486. },
  487. columns=["key", "value_x", "value_y"],
  488. )
  489. actual = df_left.merge(df_right, on="key")
  490. tm.assert_frame_equal(actual, expected)
  491. def test_merge_nosort(self):
  492. # GH#2098
  493. d = {
  494. "var1": np.random.randint(0, 10, size=10),
  495. "var2": np.random.randint(0, 10, size=10),
  496. "var3": [
  497. datetime(2012, 1, 12),
  498. datetime(2011, 2, 4),
  499. datetime(2010, 2, 3),
  500. datetime(2012, 1, 12),
  501. datetime(2011, 2, 4),
  502. datetime(2012, 4, 3),
  503. datetime(2012, 3, 4),
  504. datetime(2008, 5, 1),
  505. datetime(2010, 2, 3),
  506. datetime(2012, 2, 3),
  507. ],
  508. }
  509. df = DataFrame.from_dict(d)
  510. var3 = df.var3.unique()
  511. var3 = np.sort(var3)
  512. new = DataFrame.from_dict({"var3": var3, "var8": np.random.random(7)})
  513. result = df.merge(new, on="var3", sort=False)
  514. exp = merge(df, new, on="var3", sort=False)
  515. tm.assert_frame_equal(result, exp)
  516. assert (df.var3.unique() == result.var3.unique()).all()
  517. @pytest.mark.parametrize(
  518. ("sort", "values"), [(False, [1, 1, 0, 1, 1]), (True, [0, 1, 1, 1, 1])]
  519. )
  520. @pytest.mark.parametrize("how", ["left", "right"])
  521. def test_merge_same_order_left_right(self, sort, values, how):
  522. # GH#35382
  523. df = DataFrame({"a": [1, 0, 1]})
  524. result = df.merge(df, on="a", how=how, sort=sort)
  525. expected = DataFrame(values, columns=["a"])
  526. tm.assert_frame_equal(result, expected)
  527. def test_merge_nan_right(self):
  528. df1 = DataFrame({"i1": [0, 1], "i2": [0, 1]})
  529. df2 = DataFrame({"i1": [0], "i3": [0]})
  530. result = df1.join(df2, on="i1", rsuffix="_")
  531. expected = (
  532. DataFrame(
  533. {
  534. "i1": {0: 0.0, 1: 1},
  535. "i2": {0: 0, 1: 1},
  536. "i1_": {0: 0, 1: np.nan},
  537. "i3": {0: 0.0, 1: np.nan},
  538. None: {0: 0, 1: 0},
  539. }
  540. )
  541. .set_index(None)
  542. .reset_index()[["i1", "i2", "i1_", "i3"]]
  543. )
  544. tm.assert_frame_equal(result, expected, check_dtype=False)
  545. def test_merge_nan_right2(self):
  546. df1 = DataFrame({"i1": [0, 1], "i2": [0.5, 1.5]})
  547. df2 = DataFrame({"i1": [0], "i3": [0.7]})
  548. result = df1.join(df2, rsuffix="_", on="i1")
  549. expected = DataFrame(
  550. {
  551. "i1": {0: 0, 1: 1},
  552. "i1_": {0: 0.0, 1: np.nan},
  553. "i2": {0: 0.5, 1: 1.5},
  554. "i3": {0: 0.69999999999999996, 1: np.nan},
  555. }
  556. )[["i1", "i2", "i1_", "i3"]]
  557. tm.assert_frame_equal(result, expected)
  558. def test_merge_type(self, df, df2):
  559. class NotADataFrame(DataFrame):
  560. @property
  561. def _constructor(self):
  562. return NotADataFrame
  563. nad = NotADataFrame(df)
  564. result = nad.merge(df2, on="key1")
  565. assert isinstance(result, NotADataFrame)
  566. def test_join_append_timedeltas(self, using_array_manager):
  567. # timedelta64 issues with join/merge
  568. # GH 5695
  569. d = DataFrame.from_dict(
  570. {"d": [datetime(2013, 11, 5, 5, 56)], "t": [timedelta(0, 22500)]}
  571. )
  572. df = DataFrame(columns=list("dt"))
  573. df = concat([df, d], ignore_index=True)
  574. result = concat([df, d], ignore_index=True)
  575. expected = DataFrame(
  576. {
  577. "d": [datetime(2013, 11, 5, 5, 56), datetime(2013, 11, 5, 5, 56)],
  578. "t": [timedelta(0, 22500), timedelta(0, 22500)],
  579. }
  580. )
  581. if using_array_manager:
  582. # TODO(ArrayManager) decide on exact casting rules in concat
  583. expected = expected.astype(object)
  584. tm.assert_frame_equal(result, expected)
  585. def test_join_append_timedeltas2(self):
  586. # timedelta64 issues with join/merge
  587. # GH 5695
  588. td = np.timedelta64(300000000)
  589. lhs = DataFrame(Series([td, td], index=["A", "B"]))
  590. rhs = DataFrame(Series([td], index=["A"]))
  591. result = lhs.join(rhs, rsuffix="r", how="left")
  592. expected = DataFrame(
  593. {
  594. "0": Series([td, td], index=list("AB")),
  595. "0r": Series([td, pd.NaT], index=list("AB")),
  596. }
  597. )
  598. tm.assert_frame_equal(result, expected)
  599. @pytest.mark.parametrize("unit", ["D", "h", "m", "s", "ms", "us", "ns"])
  600. def test_other_datetime_unit(self, unit):
  601. # GH 13389
  602. df1 = DataFrame({"entity_id": [101, 102]})
  603. ser = Series([None, None], index=[101, 102], name="days")
  604. dtype = f"datetime64[{unit}]"
  605. if unit in ["D", "h", "m"]:
  606. # not supported so we cast to the nearest supported unit, seconds
  607. exp_dtype = "datetime64[s]"
  608. else:
  609. exp_dtype = dtype
  610. df2 = ser.astype(exp_dtype).to_frame("days")
  611. assert df2["days"].dtype == exp_dtype
  612. result = df1.merge(df2, left_on="entity_id", right_index=True)
  613. days = np.array(["nat", "nat"], dtype=exp_dtype)
  614. days = pd.core.arrays.DatetimeArray._simple_new(days, dtype=days.dtype)
  615. exp = DataFrame(
  616. {
  617. "entity_id": [101, 102],
  618. "days": days,
  619. },
  620. columns=["entity_id", "days"],
  621. )
  622. assert exp["days"].dtype == exp_dtype
  623. tm.assert_frame_equal(result, exp)
  624. @pytest.mark.parametrize("unit", ["D", "h", "m", "s", "ms", "us", "ns"])
  625. def test_other_timedelta_unit(self, unit):
  626. # GH 13389
  627. df1 = DataFrame({"entity_id": [101, 102]})
  628. ser = Series([None, None], index=[101, 102], name="days")
  629. dtype = f"m8[{unit}]"
  630. if unit in ["D", "h", "m"]:
  631. # We cannot astype, instead do nearest supported unit, i.e. "s"
  632. msg = "Supported resolutions are 's', 'ms', 'us', 'ns'"
  633. with pytest.raises(ValueError, match=msg):
  634. ser.astype(dtype)
  635. df2 = ser.astype("m8[s]").to_frame("days")
  636. else:
  637. df2 = ser.astype(dtype).to_frame("days")
  638. assert df2["days"].dtype == dtype
  639. result = df1.merge(df2, left_on="entity_id", right_index=True)
  640. exp = DataFrame(
  641. {"entity_id": [101, 102], "days": np.array(["nat", "nat"], dtype=dtype)},
  642. columns=["entity_id", "days"],
  643. )
  644. tm.assert_frame_equal(result, exp)
  645. def test_overlapping_columns_error_message(self):
  646. df = DataFrame({"key": [1, 2, 3], "v1": [4, 5, 6], "v2": [7, 8, 9]})
  647. df2 = DataFrame({"key": [1, 2, 3], "v1": [4, 5, 6], "v2": [7, 8, 9]})
  648. df.columns = ["key", "foo", "foo"]
  649. df2.columns = ["key", "bar", "bar"]
  650. expected = DataFrame(
  651. {
  652. "key": [1, 2, 3],
  653. "v1": [4, 5, 6],
  654. "v2": [7, 8, 9],
  655. "v3": [4, 5, 6],
  656. "v4": [7, 8, 9],
  657. }
  658. )
  659. expected.columns = ["key", "foo", "foo", "bar", "bar"]
  660. tm.assert_frame_equal(merge(df, df2), expected)
  661. # #2649, #10639
  662. df2.columns = ["key1", "foo", "foo"]
  663. msg = r"Data columns not unique: Index\(\['foo'\], dtype='object'\)"
  664. with pytest.raises(MergeError, match=msg):
  665. merge(df, df2)
  666. def test_merge_on_datetime64tz(self):
  667. # GH11405
  668. left = DataFrame(
  669. {
  670. "key": pd.date_range("20151010", periods=2, tz="US/Eastern"),
  671. "value": [1, 2],
  672. }
  673. )
  674. right = DataFrame(
  675. {
  676. "key": pd.date_range("20151011", periods=3, tz="US/Eastern"),
  677. "value": [1, 2, 3],
  678. }
  679. )
  680. expected = DataFrame(
  681. {
  682. "key": pd.date_range("20151010", periods=4, tz="US/Eastern"),
  683. "value_x": [1, 2, np.nan, np.nan],
  684. "value_y": [np.nan, 1, 2, 3],
  685. }
  686. )
  687. result = merge(left, right, on="key", how="outer")
  688. tm.assert_frame_equal(result, expected)
  689. def test_merge_datetime64tz_values(self):
  690. left = DataFrame(
  691. {
  692. "key": [1, 2],
  693. "value": pd.date_range("20151010", periods=2, tz="US/Eastern"),
  694. }
  695. )
  696. right = DataFrame(
  697. {
  698. "key": [2, 3],
  699. "value": pd.date_range("20151011", periods=2, tz="US/Eastern"),
  700. }
  701. )
  702. expected = DataFrame(
  703. {
  704. "key": [1, 2, 3],
  705. "value_x": list(pd.date_range("20151010", periods=2, tz="US/Eastern"))
  706. + [pd.NaT],
  707. "value_y": [pd.NaT]
  708. + list(pd.date_range("20151011", periods=2, tz="US/Eastern")),
  709. }
  710. )
  711. result = merge(left, right, on="key", how="outer")
  712. tm.assert_frame_equal(result, expected)
  713. assert result["value_x"].dtype == "datetime64[ns, US/Eastern]"
  714. assert result["value_y"].dtype == "datetime64[ns, US/Eastern]"
  715. def test_merge_on_datetime64tz_empty(self):
  716. # https://github.com/pandas-dev/pandas/issues/25014
  717. dtz = pd.DatetimeTZDtype(tz="UTC")
  718. right = DataFrame(
  719. {
  720. "date": [pd.Timestamp("2018", tz=dtz.tz)],
  721. "value": [4.0],
  722. "date2": [pd.Timestamp("2019", tz=dtz.tz)],
  723. },
  724. columns=["date", "value", "date2"],
  725. )
  726. left = right[:0]
  727. result = left.merge(right, on="date")
  728. expected = DataFrame(
  729. {
  730. "value_x": Series(dtype=float),
  731. "date2_x": Series(dtype=dtz),
  732. "date": Series(dtype=dtz),
  733. "value_y": Series(dtype=float),
  734. "date2_y": Series(dtype=dtz),
  735. },
  736. columns=["value_x", "date2_x", "date", "value_y", "date2_y"],
  737. )
  738. tm.assert_frame_equal(result, expected)
  739. def test_merge_datetime64tz_with_dst_transition(self):
  740. # GH 18885
  741. df1 = DataFrame(
  742. pd.date_range("2017-10-29 01:00", periods=4, freq="H", tz="Europe/Madrid"),
  743. columns=["date"],
  744. )
  745. df1["value"] = 1
  746. df2 = DataFrame(
  747. {
  748. "date": pd.to_datetime(
  749. [
  750. "2017-10-29 03:00:00",
  751. "2017-10-29 04:00:00",
  752. "2017-10-29 05:00:00",
  753. ]
  754. ),
  755. "value": 2,
  756. }
  757. )
  758. df2["date"] = df2["date"].dt.tz_localize("UTC").dt.tz_convert("Europe/Madrid")
  759. result = merge(df1, df2, how="outer", on="date")
  760. expected = DataFrame(
  761. {
  762. "date": pd.date_range(
  763. "2017-10-29 01:00", periods=7, freq="H", tz="Europe/Madrid"
  764. ),
  765. "value_x": [1] * 4 + [np.nan] * 3,
  766. "value_y": [np.nan] * 4 + [2] * 3,
  767. }
  768. )
  769. tm.assert_frame_equal(result, expected)
  770. def test_merge_non_unique_period_index(self):
  771. # GH #16871
  772. index = pd.period_range("2016-01-01", periods=16, freq="M")
  773. df = DataFrame(list(range(len(index))), index=index, columns=["pnum"])
  774. df2 = concat([df, df])
  775. result = df.merge(df2, left_index=True, right_index=True, how="inner")
  776. expected = DataFrame(
  777. np.tile(np.arange(16, dtype=np.int64).repeat(2).reshape(-1, 1), 2),
  778. columns=["pnum_x", "pnum_y"],
  779. index=df2.sort_index().index,
  780. )
  781. tm.assert_frame_equal(result, expected)
  782. def test_merge_on_periods(self):
  783. left = DataFrame(
  784. {"key": pd.period_range("20151010", periods=2, freq="D"), "value": [1, 2]}
  785. )
  786. right = DataFrame(
  787. {
  788. "key": pd.period_range("20151011", periods=3, freq="D"),
  789. "value": [1, 2, 3],
  790. }
  791. )
  792. expected = DataFrame(
  793. {
  794. "key": pd.period_range("20151010", periods=4, freq="D"),
  795. "value_x": [1, 2, np.nan, np.nan],
  796. "value_y": [np.nan, 1, 2, 3],
  797. }
  798. )
  799. result = merge(left, right, on="key", how="outer")
  800. tm.assert_frame_equal(result, expected)
  801. def test_merge_period_values(self):
  802. left = DataFrame(
  803. {"key": [1, 2], "value": pd.period_range("20151010", periods=2, freq="D")}
  804. )
  805. right = DataFrame(
  806. {"key": [2, 3], "value": pd.period_range("20151011", periods=2, freq="D")}
  807. )
  808. exp_x = pd.period_range("20151010", periods=2, freq="D")
  809. exp_y = pd.period_range("20151011", periods=2, freq="D")
  810. expected = DataFrame(
  811. {
  812. "key": [1, 2, 3],
  813. "value_x": list(exp_x) + [pd.NaT],
  814. "value_y": [pd.NaT] + list(exp_y),
  815. }
  816. )
  817. result = merge(left, right, on="key", how="outer")
  818. tm.assert_frame_equal(result, expected)
  819. assert result["value_x"].dtype == "Period[D]"
  820. assert result["value_y"].dtype == "Period[D]"
  821. def test_indicator(self, dfs_for_indicator):
  822. # PR #10054. xref #7412 and closes #8790.
  823. df1, df2 = dfs_for_indicator
  824. df1_copy = df1.copy()
  825. df2_copy = df2.copy()
  826. df_result = DataFrame(
  827. {
  828. "col1": [0, 1, 2, 3, 4, 5],
  829. "col_conflict_x": [1, 2, np.nan, np.nan, np.nan, np.nan],
  830. "col_left": ["a", "b", np.nan, np.nan, np.nan, np.nan],
  831. "col_conflict_y": [np.nan, 1, 2, 3, 4, 5],
  832. "col_right": [np.nan, 2, 2, 2, 2, 2],
  833. }
  834. )
  835. df_result["_merge"] = Categorical(
  836. [
  837. "left_only",
  838. "both",
  839. "right_only",
  840. "right_only",
  841. "right_only",
  842. "right_only",
  843. ],
  844. categories=["left_only", "right_only", "both"],
  845. )
  846. df_result = df_result[
  847. [
  848. "col1",
  849. "col_conflict_x",
  850. "col_left",
  851. "col_conflict_y",
  852. "col_right",
  853. "_merge",
  854. ]
  855. ]
  856. test = merge(df1, df2, on="col1", how="outer", indicator=True)
  857. tm.assert_frame_equal(test, df_result)
  858. test = df1.merge(df2, on="col1", how="outer", indicator=True)
  859. tm.assert_frame_equal(test, df_result)
  860. # No side effects
  861. tm.assert_frame_equal(df1, df1_copy)
  862. tm.assert_frame_equal(df2, df2_copy)
  863. # Check with custom name
  864. df_result_custom_name = df_result
  865. df_result_custom_name = df_result_custom_name.rename(
  866. columns={"_merge": "custom_name"}
  867. )
  868. test_custom_name = merge(
  869. df1, df2, on="col1", how="outer", indicator="custom_name"
  870. )
  871. tm.assert_frame_equal(test_custom_name, df_result_custom_name)
  872. test_custom_name = df1.merge(
  873. df2, on="col1", how="outer", indicator="custom_name"
  874. )
  875. tm.assert_frame_equal(test_custom_name, df_result_custom_name)
  876. def test_merge_indicator_arg_validation(self, dfs_for_indicator):
  877. # Check only accepts strings and booleans
  878. df1, df2 = dfs_for_indicator
  879. msg = "indicator option can only accept boolean or string arguments"
  880. with pytest.raises(ValueError, match=msg):
  881. merge(df1, df2, on="col1", how="outer", indicator=5)
  882. with pytest.raises(ValueError, match=msg):
  883. df1.merge(df2, on="col1", how="outer", indicator=5)
  884. def test_merge_indicator_result_integrity(self, dfs_for_indicator):
  885. # Check result integrity
  886. df1, df2 = dfs_for_indicator
  887. test2 = merge(df1, df2, on="col1", how="left", indicator=True)
  888. assert (test2._merge != "right_only").all()
  889. test2 = df1.merge(df2, on="col1", how="left", indicator=True)
  890. assert (test2._merge != "right_only").all()
  891. test3 = merge(df1, df2, on="col1", how="right", indicator=True)
  892. assert (test3._merge != "left_only").all()
  893. test3 = df1.merge(df2, on="col1", how="right", indicator=True)
  894. assert (test3._merge != "left_only").all()
  895. test4 = merge(df1, df2, on="col1", how="inner", indicator=True)
  896. assert (test4._merge == "both").all()
  897. test4 = df1.merge(df2, on="col1", how="inner", indicator=True)
  898. assert (test4._merge == "both").all()
  899. def test_merge_indicator_invalid(self, dfs_for_indicator):
  900. # Check if working name in df
  901. df1, _ = dfs_for_indicator
  902. for i in ["_right_indicator", "_left_indicator", "_merge"]:
  903. df_badcolumn = DataFrame({"col1": [1, 2], i: [2, 2]})
  904. msg = (
  905. "Cannot use `indicator=True` option when data contains a "
  906. f"column named {i}|"
  907. "Cannot use name of an existing column for indicator column"
  908. )
  909. with pytest.raises(ValueError, match=msg):
  910. merge(df1, df_badcolumn, on="col1", how="outer", indicator=True)
  911. with pytest.raises(ValueError, match=msg):
  912. df1.merge(df_badcolumn, on="col1", how="outer", indicator=True)
  913. # Check for name conflict with custom name
  914. df_badcolumn = DataFrame({"col1": [1, 2], "custom_column_name": [2, 2]})
  915. msg = "Cannot use name of an existing column for indicator column"
  916. with pytest.raises(ValueError, match=msg):
  917. merge(
  918. df1,
  919. df_badcolumn,
  920. on="col1",
  921. how="outer",
  922. indicator="custom_column_name",
  923. )
  924. with pytest.raises(ValueError, match=msg):
  925. df1.merge(
  926. df_badcolumn, on="col1", how="outer", indicator="custom_column_name"
  927. )
  928. def test_merge_indicator_multiple_columns(self):
  929. # Merge on multiple columns
  930. df3 = DataFrame({"col1": [0, 1], "col2": ["a", "b"]})
  931. df4 = DataFrame({"col1": [1, 1, 3], "col2": ["b", "x", "y"]})
  932. hand_coded_result = DataFrame(
  933. {"col1": [0, 1, 1, 3], "col2": ["a", "b", "x", "y"]}
  934. )
  935. hand_coded_result["_merge"] = Categorical(
  936. ["left_only", "both", "right_only", "right_only"],
  937. categories=["left_only", "right_only", "both"],
  938. )
  939. test5 = merge(df3, df4, on=["col1", "col2"], how="outer", indicator=True)
  940. tm.assert_frame_equal(test5, hand_coded_result)
  941. test5 = df3.merge(df4, on=["col1", "col2"], how="outer", indicator=True)
  942. tm.assert_frame_equal(test5, hand_coded_result)
  943. def test_validation(self):
  944. left = DataFrame(
  945. {"a": ["a", "b", "c", "d"], "b": ["cat", "dog", "weasel", "horse"]},
  946. index=range(4),
  947. )
  948. right = DataFrame(
  949. {
  950. "a": ["a", "b", "c", "d", "e"],
  951. "c": ["meow", "bark", "um... weasel noise?", "nay", "chirp"],
  952. },
  953. index=range(5),
  954. )
  955. # Make sure no side effects.
  956. left_copy = left.copy()
  957. right_copy = right.copy()
  958. result = merge(left, right, left_index=True, right_index=True, validate="1:1")
  959. tm.assert_frame_equal(left, left_copy)
  960. tm.assert_frame_equal(right, right_copy)
  961. # make sure merge still correct
  962. expected = DataFrame(
  963. {
  964. "a_x": ["a", "b", "c", "d"],
  965. "b": ["cat", "dog", "weasel", "horse"],
  966. "a_y": ["a", "b", "c", "d"],
  967. "c": ["meow", "bark", "um... weasel noise?", "nay"],
  968. },
  969. index=range(4),
  970. columns=["a_x", "b", "a_y", "c"],
  971. )
  972. result = merge(
  973. left, right, left_index=True, right_index=True, validate="one_to_one"
  974. )
  975. tm.assert_frame_equal(result, expected)
  976. expected_2 = DataFrame(
  977. {
  978. "a": ["a", "b", "c", "d"],
  979. "b": ["cat", "dog", "weasel", "horse"],
  980. "c": ["meow", "bark", "um... weasel noise?", "nay"],
  981. },
  982. index=range(4),
  983. )
  984. result = merge(left, right, on="a", validate="1:1")
  985. tm.assert_frame_equal(left, left_copy)
  986. tm.assert_frame_equal(right, right_copy)
  987. tm.assert_frame_equal(result, expected_2)
  988. result = merge(left, right, on="a", validate="one_to_one")
  989. tm.assert_frame_equal(result, expected_2)
  990. # One index, one column
  991. expected_3 = DataFrame(
  992. {
  993. "b": ["cat", "dog", "weasel", "horse"],
  994. "a": ["a", "b", "c", "d"],
  995. "c": ["meow", "bark", "um... weasel noise?", "nay"],
  996. },
  997. columns=["b", "a", "c"],
  998. index=range(4),
  999. )
  1000. left_index_reset = left.set_index("a")
  1001. result = merge(
  1002. left_index_reset,
  1003. right,
  1004. left_index=True,
  1005. right_on="a",
  1006. validate="one_to_one",
  1007. )
  1008. tm.assert_frame_equal(result, expected_3)
  1009. # Dups on right
  1010. right_w_dups = concat([right, DataFrame({"a": ["e"], "c": ["moo"]}, index=[4])])
  1011. merge(
  1012. left,
  1013. right_w_dups,
  1014. left_index=True,
  1015. right_index=True,
  1016. validate="one_to_many",
  1017. )
  1018. msg = "Merge keys are not unique in right dataset; not a one-to-one merge"
  1019. with pytest.raises(MergeError, match=msg):
  1020. merge(
  1021. left,
  1022. right_w_dups,
  1023. left_index=True,
  1024. right_index=True,
  1025. validate="one_to_one",
  1026. )
  1027. with pytest.raises(MergeError, match=msg):
  1028. merge(left, right_w_dups, on="a", validate="one_to_one")
  1029. # Dups on left
  1030. left_w_dups = concat(
  1031. [left, DataFrame({"a": ["a"], "c": ["cow"]}, index=[3])], sort=True
  1032. )
  1033. merge(
  1034. left_w_dups,
  1035. right,
  1036. left_index=True,
  1037. right_index=True,
  1038. validate="many_to_one",
  1039. )
  1040. msg = "Merge keys are not unique in left dataset; not a one-to-one merge"
  1041. with pytest.raises(MergeError, match=msg):
  1042. merge(
  1043. left_w_dups,
  1044. right,
  1045. left_index=True,
  1046. right_index=True,
  1047. validate="one_to_one",
  1048. )
  1049. with pytest.raises(MergeError, match=msg):
  1050. merge(left_w_dups, right, on="a", validate="one_to_one")
  1051. # Dups on both
  1052. merge(left_w_dups, right_w_dups, on="a", validate="many_to_many")
  1053. msg = "Merge keys are not unique in right dataset; not a many-to-one merge"
  1054. with pytest.raises(MergeError, match=msg):
  1055. merge(
  1056. left_w_dups,
  1057. right_w_dups,
  1058. left_index=True,
  1059. right_index=True,
  1060. validate="many_to_one",
  1061. )
  1062. msg = "Merge keys are not unique in left dataset; not a one-to-many merge"
  1063. with pytest.raises(MergeError, match=msg):
  1064. merge(left_w_dups, right_w_dups, on="a", validate="one_to_many")
  1065. # Check invalid arguments
  1066. msg = (
  1067. '"jibberish" is not a valid argument. '
  1068. "Valid arguments are:\n"
  1069. '- "1:1"\n'
  1070. '- "1:m"\n'
  1071. '- "m:1"\n'
  1072. '- "m:m"\n'
  1073. '- "one_to_one"\n'
  1074. '- "one_to_many"\n'
  1075. '- "many_to_one"\n'
  1076. '- "many_to_many"'
  1077. )
  1078. with pytest.raises(ValueError, match=msg):
  1079. merge(left, right, on="a", validate="jibberish")
  1080. # Two column merge, dups in both, but jointly no dups.
  1081. left = DataFrame(
  1082. {
  1083. "a": ["a", "a", "b", "b"],
  1084. "b": [0, 1, 0, 1],
  1085. "c": ["cat", "dog", "weasel", "horse"],
  1086. },
  1087. index=range(4),
  1088. )
  1089. right = DataFrame(
  1090. {
  1091. "a": ["a", "a", "b"],
  1092. "b": [0, 1, 0],
  1093. "d": ["meow", "bark", "um... weasel noise?"],
  1094. },
  1095. index=range(3),
  1096. )
  1097. expected_multi = DataFrame(
  1098. {
  1099. "a": ["a", "a", "b"],
  1100. "b": [0, 1, 0],
  1101. "c": ["cat", "dog", "weasel"],
  1102. "d": ["meow", "bark", "um... weasel noise?"],
  1103. },
  1104. index=range(3),
  1105. )
  1106. msg = (
  1107. "Merge keys are not unique in either left or right dataset; "
  1108. "not a one-to-one merge"
  1109. )
  1110. with pytest.raises(MergeError, match=msg):
  1111. merge(left, right, on="a", validate="1:1")
  1112. result = merge(left, right, on=["a", "b"], validate="1:1")
  1113. tm.assert_frame_equal(result, expected_multi)
  1114. def test_merge_two_empty_df_no_division_error(self):
  1115. # GH17776, PR #17846
  1116. a = DataFrame({"a": [], "b": [], "c": []})
  1117. with np.errstate(divide="raise"):
  1118. merge(a, a, on=("a", "b"))
  1119. @pytest.mark.parametrize("how", ["right", "outer"])
  1120. @pytest.mark.parametrize(
  1121. "index,expected_index",
  1122. [
  1123. (
  1124. CategoricalIndex([1, 2, 4]),
  1125. CategoricalIndex([1, 2, 4, None, None, None]),
  1126. ),
  1127. (
  1128. DatetimeIndex(["2001-01-01", "2002-02-02", "2003-03-03"]),
  1129. DatetimeIndex(
  1130. ["2001-01-01", "2002-02-02", "2003-03-03", pd.NaT, pd.NaT, pd.NaT]
  1131. ),
  1132. ),
  1133. *[
  1134. (
  1135. Index([1, 2, 3], dtype=dtyp),
  1136. Index([1, 2, 3, None, None, None], dtype=np.float64),
  1137. )
  1138. for dtyp in tm.ALL_REAL_NUMPY_DTYPES
  1139. ],
  1140. (
  1141. IntervalIndex.from_tuples([(1, 2), (2, 3), (3, 4)]),
  1142. IntervalIndex.from_tuples(
  1143. [(1, 2), (2, 3), (3, 4), np.nan, np.nan, np.nan]
  1144. ),
  1145. ),
  1146. (
  1147. PeriodIndex(["2001-01-01", "2001-01-02", "2001-01-03"], freq="D"),
  1148. PeriodIndex(
  1149. ["2001-01-01", "2001-01-02", "2001-01-03", pd.NaT, pd.NaT, pd.NaT],
  1150. freq="D",
  1151. ),
  1152. ),
  1153. (
  1154. TimedeltaIndex(["1d", "2d", "3d"]),
  1155. TimedeltaIndex(["1d", "2d", "3d", pd.NaT, pd.NaT, pd.NaT]),
  1156. ),
  1157. ],
  1158. )
  1159. def test_merge_on_index_with_more_values(self, how, index, expected_index):
  1160. # GH 24212
  1161. # pd.merge gets [0, 1, 2, -1, -1, -1] as left_indexer, ensure that
  1162. # -1 is interpreted as a missing value instead of the last element
  1163. df1 = DataFrame({"a": [0, 1, 2], "key": [0, 1, 2]}, index=index)
  1164. df2 = DataFrame({"b": [0, 1, 2, 3, 4, 5]})
  1165. result = df1.merge(df2, left_on="key", right_index=True, how=how)
  1166. expected = DataFrame(
  1167. [
  1168. [0, 0, 0],
  1169. [1, 1, 1],
  1170. [2, 2, 2],
  1171. [np.nan, 3, 3],
  1172. [np.nan, 4, 4],
  1173. [np.nan, 5, 5],
  1174. ],
  1175. columns=["a", "key", "b"],
  1176. )
  1177. expected.set_index(expected_index, inplace=True)
  1178. tm.assert_frame_equal(result, expected)
  1179. def test_merge_right_index_right(self):
  1180. # Note: the expected output here is probably incorrect.
  1181. # See https://github.com/pandas-dev/pandas/issues/17257 for more.
  1182. # We include this as a regression test for GH-24897.
  1183. left = DataFrame({"a": [1, 2, 3], "key": [0, 1, 1]})
  1184. right = DataFrame({"b": [1, 2, 3]})
  1185. expected = DataFrame(
  1186. {"a": [1, 2, 3, None], "key": [0, 1, 1, 2], "b": [1, 2, 2, 3]},
  1187. columns=["a", "key", "b"],
  1188. index=[0, 1, 2, np.nan],
  1189. )
  1190. result = left.merge(right, left_on="key", right_index=True, how="right")
  1191. tm.assert_frame_equal(result, expected)
  1192. @pytest.mark.parametrize("how", ["left", "right"])
  1193. def test_merge_preserves_row_order(self, how):
  1194. # GH 27453
  1195. left_df = DataFrame({"animal": ["dog", "pig"], "max_speed": [40, 11]})
  1196. right_df = DataFrame({"animal": ["quetzal", "pig"], "max_speed": [80, 11]})
  1197. result = left_df.merge(right_df, on=["animal", "max_speed"], how=how)
  1198. if how == "right":
  1199. expected = DataFrame({"animal": ["quetzal", "pig"], "max_speed": [80, 11]})
  1200. else:
  1201. expected = DataFrame({"animal": ["dog", "pig"], "max_speed": [40, 11]})
  1202. tm.assert_frame_equal(result, expected)
  1203. def test_merge_take_missing_values_from_index_of_other_dtype(self):
  1204. # GH 24212
  1205. left = DataFrame(
  1206. {
  1207. "a": [1, 2, 3],
  1208. "key": Categorical(["a", "a", "b"], categories=list("abc")),
  1209. }
  1210. )
  1211. right = DataFrame({"b": [1, 2, 3]}, index=CategoricalIndex(["a", "b", "c"]))
  1212. result = left.merge(right, left_on="key", right_index=True, how="right")
  1213. expected = DataFrame(
  1214. {
  1215. "a": [1, 2, 3, None],
  1216. "key": Categorical(["a", "a", "b", "c"]),
  1217. "b": [1, 1, 2, 3],
  1218. },
  1219. index=[0, 1, 2, np.nan],
  1220. )
  1221. expected = expected.reindex(columns=["a", "key", "b"])
  1222. tm.assert_frame_equal(result, expected)
  1223. def test_merge_readonly(self):
  1224. # https://github.com/pandas-dev/pandas/issues/27943
  1225. data1 = DataFrame(
  1226. np.arange(20).reshape((4, 5)) + 1, columns=["a", "b", "c", "d", "e"]
  1227. )
  1228. data2 = DataFrame(
  1229. np.arange(20).reshape((5, 4)) + 1, columns=["a", "b", "x", "y"]
  1230. )
  1231. # make each underlying block array / column array read-only
  1232. for arr in data1._mgr.arrays:
  1233. arr.flags.writeable = False
  1234. data1.merge(data2) # no error
  1235. def _check_merge(x, y):
  1236. for how in ["inner", "left", "outer"]:
  1237. result = x.join(y, how=how)
  1238. expected = merge(x.reset_index(), y.reset_index(), how=how, sort=True)
  1239. expected = expected.set_index("index")
  1240. # TODO check_names on merge?
  1241. tm.assert_frame_equal(result, expected, check_names=False)
  1242. class TestMergeDtypes:
  1243. @pytest.mark.parametrize(
  1244. "right_vals", [["foo", "bar"], Series(["foo", "bar"]).astype("category")]
  1245. )
  1246. def test_different(self, right_vals):
  1247. left = DataFrame(
  1248. {
  1249. "A": ["foo", "bar"],
  1250. "B": Series(["foo", "bar"]).astype("category"),
  1251. "C": [1, 2],
  1252. "D": [1.0, 2.0],
  1253. "E": Series([1, 2], dtype="uint64"),
  1254. "F": Series([1, 2], dtype="int32"),
  1255. }
  1256. )
  1257. right = DataFrame({"A": right_vals})
  1258. # GH 9780
  1259. # We allow merging on object and categorical cols and cast
  1260. # categorical cols to object
  1261. result = merge(left, right, on="A")
  1262. assert is_object_dtype(result.A.dtype)
  1263. @pytest.mark.parametrize(
  1264. "d1", [np.int64, np.int32, np.intc, np.int16, np.int8, np.uint8]
  1265. )
  1266. @pytest.mark.parametrize("d2", [np.int64, np.float64, np.float32, np.float16])
  1267. def test_join_multi_dtypes(self, d1, d2):
  1268. dtype1 = np.dtype(d1)
  1269. dtype2 = np.dtype(d2)
  1270. left = DataFrame(
  1271. {
  1272. "k1": np.array([0, 1, 2] * 8, dtype=dtype1),
  1273. "k2": ["foo", "bar"] * 12,
  1274. "v": np.array(np.arange(24), dtype=np.int64),
  1275. }
  1276. )
  1277. index = MultiIndex.from_tuples([(2, "bar"), (1, "foo")])
  1278. right = DataFrame({"v2": np.array([5, 7], dtype=dtype2)}, index=index)
  1279. result = left.join(right, on=["k1", "k2"])
  1280. expected = left.copy()
  1281. if dtype2.kind == "i":
  1282. dtype2 = np.dtype("float64")
  1283. expected["v2"] = np.array(np.nan, dtype=dtype2)
  1284. expected.loc[(expected.k1 == 2) & (expected.k2 == "bar"), "v2"] = 5
  1285. expected.loc[(expected.k1 == 1) & (expected.k2 == "foo"), "v2"] = 7
  1286. tm.assert_frame_equal(result, expected)
  1287. result = left.join(right, on=["k1", "k2"], sort=True)
  1288. expected.sort_values(["k1", "k2"], kind="mergesort", inplace=True)
  1289. tm.assert_frame_equal(result, expected)
  1290. @pytest.mark.parametrize(
  1291. "int_vals, float_vals, exp_vals",
  1292. [
  1293. ([1, 2, 3], [1.0, 2.0, 3.0], {"X": [1, 2, 3], "Y": [1.0, 2.0, 3.0]}),
  1294. ([1, 2, 3], [1.0, 3.0], {"X": [1, 3], "Y": [1.0, 3.0]}),
  1295. ([1, 2], [1.0, 2.0, 3.0], {"X": [1, 2], "Y": [1.0, 2.0]}),
  1296. ],
  1297. )
  1298. def test_merge_on_ints_floats(self, int_vals, float_vals, exp_vals):
  1299. # GH 16572
  1300. # Check that float column is not cast to object if
  1301. # merging on float and int columns
  1302. A = DataFrame({"X": int_vals})
  1303. B = DataFrame({"Y": float_vals})
  1304. expected = DataFrame(exp_vals)
  1305. result = A.merge(B, left_on="X", right_on="Y")
  1306. tm.assert_frame_equal(result, expected)
  1307. result = B.merge(A, left_on="Y", right_on="X")
  1308. tm.assert_frame_equal(result, expected[["Y", "X"]])
  1309. def test_merge_key_dtype_cast(self):
  1310. # GH 17044
  1311. df1 = DataFrame({"key": [1.0, 2.0], "v1": [10, 20]}, columns=["key", "v1"])
  1312. df2 = DataFrame({"key": [2], "v2": [200]}, columns=["key", "v2"])
  1313. result = df1.merge(df2, on="key", how="left")
  1314. expected = DataFrame(
  1315. {"key": [1.0, 2.0], "v1": [10, 20], "v2": [np.nan, 200.0]},
  1316. columns=["key", "v1", "v2"],
  1317. )
  1318. tm.assert_frame_equal(result, expected)
  1319. def test_merge_on_ints_floats_warning(self):
  1320. # GH 16572
  1321. # merge will produce a warning when merging on int and
  1322. # float columns where the float values are not exactly
  1323. # equal to their int representation
  1324. A = DataFrame({"X": [1, 2, 3]})
  1325. B = DataFrame({"Y": [1.1, 2.5, 3.0]})
  1326. expected = DataFrame({"X": [3], "Y": [3.0]})
  1327. with tm.assert_produces_warning(UserWarning):
  1328. result = A.merge(B, left_on="X", right_on="Y")
  1329. tm.assert_frame_equal(result, expected)
  1330. with tm.assert_produces_warning(UserWarning):
  1331. result = B.merge(A, left_on="Y", right_on="X")
  1332. tm.assert_frame_equal(result, expected[["Y", "X"]])
  1333. # test no warning if float has NaNs
  1334. B = DataFrame({"Y": [np.nan, np.nan, 3.0]})
  1335. with tm.assert_produces_warning(None):
  1336. result = B.merge(A, left_on="Y", right_on="X")
  1337. tm.assert_frame_equal(result, expected[["Y", "X"]])
  1338. def test_merge_incompat_infer_boolean_object(self):
  1339. # GH21119: bool + object bool merge OK
  1340. df1 = DataFrame({"key": Series([True, False], dtype=object)})
  1341. df2 = DataFrame({"key": [True, False]})
  1342. expected = DataFrame({"key": [True, False]}, dtype=object)
  1343. result = merge(df1, df2, on="key")
  1344. tm.assert_frame_equal(result, expected)
  1345. result = merge(df2, df1, on="key")
  1346. tm.assert_frame_equal(result, expected)
  1347. def test_merge_incompat_infer_boolean_object_with_missing(self):
  1348. # GH21119: bool + object bool merge OK
  1349. # with missing value
  1350. df1 = DataFrame({"key": Series([True, False, np.nan], dtype=object)})
  1351. df2 = DataFrame({"key": [True, False]})
  1352. expected = DataFrame({"key": [True, False]}, dtype=object)
  1353. result = merge(df1, df2, on="key")
  1354. tm.assert_frame_equal(result, expected)
  1355. result = merge(df2, df1, on="key")
  1356. tm.assert_frame_equal(result, expected)
  1357. @pytest.mark.parametrize(
  1358. "df1_vals, df2_vals",
  1359. [
  1360. # merge on category coerces to object
  1361. ([0, 1, 2], Series(["a", "b", "a"]).astype("category")),
  1362. ([0.0, 1.0, 2.0], Series(["a", "b", "a"]).astype("category")),
  1363. # no not infer
  1364. ([0, 1], Series([False, True], dtype=object)),
  1365. ([0, 1], Series([False, True], dtype=bool)),
  1366. ],
  1367. )
  1368. def test_merge_incompat_dtypes_are_ok(self, df1_vals, df2_vals):
  1369. # these are explicitly allowed incompat merges, that pass thru
  1370. # the result type is dependent on if the values on the rhs are
  1371. # inferred, otherwise these will be coerced to object
  1372. df1 = DataFrame({"A": df1_vals})
  1373. df2 = DataFrame({"A": df2_vals})
  1374. result = merge(df1, df2, on=["A"])
  1375. assert is_object_dtype(result.A.dtype)
  1376. result = merge(df2, df1, on=["A"])
  1377. assert is_object_dtype(result.A.dtype)
  1378. @pytest.mark.parametrize(
  1379. "df1_vals, df2_vals",
  1380. [
  1381. # do not infer to numeric
  1382. (Series([1, 2], dtype="uint64"), ["a", "b", "c"]),
  1383. (Series([1, 2], dtype="int32"), ["a", "b", "c"]),
  1384. ([0, 1, 2], ["0", "1", "2"]),
  1385. ([0.0, 1.0, 2.0], ["0", "1", "2"]),
  1386. ([0, 1, 2], ["0", "1", "2"]),
  1387. (
  1388. pd.date_range("1/1/2011", periods=2, freq="D"),
  1389. ["2011-01-01", "2011-01-02"],
  1390. ),
  1391. (pd.date_range("1/1/2011", periods=2, freq="D"), [0, 1]),
  1392. (pd.date_range("1/1/2011", periods=2, freq="D"), [0.0, 1.0]),
  1393. (
  1394. pd.date_range("20130101", periods=3),
  1395. pd.date_range("20130101", periods=3, tz="US/Eastern"),
  1396. ),
  1397. ],
  1398. )
  1399. def test_merge_incompat_dtypes_error(self, df1_vals, df2_vals):
  1400. # GH 9780, GH 15800
  1401. # Raise a ValueError when a user tries to merge on
  1402. # dtypes that are incompatible (e.g., obj and int/float)
  1403. df1 = DataFrame({"A": df1_vals})
  1404. df2 = DataFrame({"A": df2_vals})
  1405. msg = (
  1406. f"You are trying to merge on {df1['A'].dtype} and "
  1407. f"{df2['A'].dtype} columns. If you wish to proceed "
  1408. "you should use pd.concat"
  1409. )
  1410. msg = re.escape(msg)
  1411. with pytest.raises(ValueError, match=msg):
  1412. merge(df1, df2, on=["A"])
  1413. # Check that error still raised when swapping order of dataframes
  1414. msg = (
  1415. f"You are trying to merge on {df2['A'].dtype} and "
  1416. f"{df1['A'].dtype} columns. If you wish to proceed "
  1417. "you should use pd.concat"
  1418. )
  1419. msg = re.escape(msg)
  1420. with pytest.raises(ValueError, match=msg):
  1421. merge(df2, df1, on=["A"])
  1422. @pytest.mark.parametrize(
  1423. "expected_data, how",
  1424. [
  1425. ([1, 2], "outer"),
  1426. ([], "inner"),
  1427. ([2], "right"),
  1428. ([1], "left"),
  1429. ],
  1430. )
  1431. def test_merge_EA_dtype(self, any_numeric_ea_dtype, how, expected_data):
  1432. # GH#40073
  1433. d1 = DataFrame([(1,)], columns=["id"], dtype=any_numeric_ea_dtype)
  1434. d2 = DataFrame([(2,)], columns=["id"], dtype=any_numeric_ea_dtype)
  1435. result = merge(d1, d2, how=how)
  1436. exp_index = RangeIndex(len(expected_data))
  1437. expected = DataFrame(
  1438. expected_data, index=exp_index, columns=["id"], dtype=any_numeric_ea_dtype
  1439. )
  1440. tm.assert_frame_equal(result, expected)
  1441. @pytest.mark.parametrize(
  1442. "expected_data, how",
  1443. [
  1444. (["a", "b"], "outer"),
  1445. ([], "inner"),
  1446. (["b"], "right"),
  1447. (["a"], "left"),
  1448. ],
  1449. )
  1450. def test_merge_string_dtype(self, how, expected_data, any_string_dtype):
  1451. # GH#40073
  1452. d1 = DataFrame([("a",)], columns=["id"], dtype=any_string_dtype)
  1453. d2 = DataFrame([("b",)], columns=["id"], dtype=any_string_dtype)
  1454. result = merge(d1, d2, how=how)
  1455. exp_idx = RangeIndex(len(expected_data))
  1456. expected = DataFrame(
  1457. expected_data, index=exp_idx, columns=["id"], dtype=any_string_dtype
  1458. )
  1459. tm.assert_frame_equal(result, expected)
  1460. @pytest.mark.parametrize(
  1461. "how, expected_data",
  1462. [
  1463. ("inner", [[True, 1, 4], [False, 5, 3]]),
  1464. ("outer", [[True, 1, 4], [False, 5, 3]]),
  1465. ("left", [[True, 1, 4], [False, 5, 3]]),
  1466. ("right", [[False, 5, 3], [True, 1, 4]]),
  1467. ],
  1468. )
  1469. def test_merge_bool_dtype(self, how, expected_data):
  1470. # GH#40073
  1471. df1 = DataFrame({"A": [True, False], "B": [1, 5]})
  1472. df2 = DataFrame({"A": [False, True], "C": [3, 4]})
  1473. result = merge(df1, df2, how=how)
  1474. expected = DataFrame(expected_data, columns=["A", "B", "C"])
  1475. tm.assert_frame_equal(result, expected)
  1476. def test_merge_ea_with_string(self, join_type, string_dtype):
  1477. # GH 43734 Avoid the use of `assign` with multi-index
  1478. df1 = DataFrame(
  1479. data={
  1480. ("lvl0", "lvl1-a"): ["1", "2", "3", "4", None],
  1481. ("lvl0", "lvl1-b"): ["4", "5", "6", "7", "8"],
  1482. },
  1483. dtype=pd.StringDtype(),
  1484. )
  1485. df1_copy = df1.copy()
  1486. df2 = DataFrame(
  1487. data={
  1488. ("lvl0", "lvl1-a"): ["1", "2", "3", pd.NA, "5"],
  1489. ("lvl0", "lvl1-c"): ["7", "8", "9", pd.NA, "11"],
  1490. },
  1491. dtype=string_dtype,
  1492. )
  1493. df2_copy = df2.copy()
  1494. merged = merge(left=df1, right=df2, on=[("lvl0", "lvl1-a")], how=join_type)
  1495. # No change in df1 and df2
  1496. tm.assert_frame_equal(df1, df1_copy)
  1497. tm.assert_frame_equal(df2, df2_copy)
  1498. # Check the expected types for the merged data frame
  1499. expected = Series(
  1500. [np.dtype("O"), pd.StringDtype(), np.dtype("O")],
  1501. index=MultiIndex.from_tuples(
  1502. [("lvl0", "lvl1-a"), ("lvl0", "lvl1-b"), ("lvl0", "lvl1-c")]
  1503. ),
  1504. )
  1505. tm.assert_series_equal(merged.dtypes, expected)
  1506. @pytest.mark.parametrize(
  1507. "left_empty, how, exp",
  1508. [
  1509. (False, "left", "left"),
  1510. (False, "right", "empty"),
  1511. (False, "inner", "empty"),
  1512. (False, "outer", "left"),
  1513. (False, "cross", "empty_cross"),
  1514. (True, "left", "empty"),
  1515. (True, "right", "right"),
  1516. (True, "inner", "empty"),
  1517. (True, "outer", "right"),
  1518. (True, "cross", "empty_cross"),
  1519. ],
  1520. )
  1521. def test_merge_empty(self, left_empty, how, exp):
  1522. left = DataFrame({"A": [2, 1], "B": [3, 4]})
  1523. right = DataFrame({"A": [1], "C": [5]}, dtype="int64")
  1524. if left_empty:
  1525. left = left.head(0)
  1526. else:
  1527. right = right.head(0)
  1528. result = left.merge(right, how=how)
  1529. if exp == "left":
  1530. expected = DataFrame({"A": [2, 1], "B": [3, 4], "C": [np.nan, np.nan]})
  1531. elif exp == "right":
  1532. expected = DataFrame({"B": [np.nan], "A": [1], "C": [5]})
  1533. elif exp == "empty":
  1534. expected = DataFrame(columns=["A", "B", "C"], dtype="int64")
  1535. if left_empty:
  1536. expected = expected[["B", "A", "C"]]
  1537. elif exp == "empty_cross":
  1538. expected = DataFrame(columns=["A_x", "B", "A_y", "C"], dtype="int64")
  1539. tm.assert_frame_equal(result, expected)
  1540. @pytest.fixture
  1541. def left():
  1542. np.random.seed(1234)
  1543. return DataFrame(
  1544. {
  1545. "X": Series(np.random.choice(["foo", "bar"], size=(10,))).astype(
  1546. CDT(["foo", "bar"])
  1547. ),
  1548. "Y": np.random.choice(["one", "two", "three"], size=(10,)),
  1549. }
  1550. )
  1551. @pytest.fixture
  1552. def right():
  1553. np.random.seed(1234)
  1554. return DataFrame(
  1555. {"X": Series(["foo", "bar"]).astype(CDT(["foo", "bar"])), "Z": [1, 2]}
  1556. )
  1557. class TestMergeCategorical:
  1558. def test_identical(self, left):
  1559. # merging on the same, should preserve dtypes
  1560. merged = merge(left, left, on="X")
  1561. result = merged.dtypes.sort_index()
  1562. expected = Series(
  1563. [CategoricalDtype(categories=["foo", "bar"]), np.dtype("O"), np.dtype("O")],
  1564. index=["X", "Y_x", "Y_y"],
  1565. )
  1566. tm.assert_series_equal(result, expected)
  1567. def test_basic(self, left, right):
  1568. # we have matching Categorical dtypes in X
  1569. # so should preserve the merged column
  1570. merged = merge(left, right, on="X")
  1571. result = merged.dtypes.sort_index()
  1572. expected = Series(
  1573. [
  1574. CategoricalDtype(categories=["foo", "bar"]),
  1575. np.dtype("O"),
  1576. np.dtype("int64"),
  1577. ],
  1578. index=["X", "Y", "Z"],
  1579. )
  1580. tm.assert_series_equal(result, expected)
  1581. def test_merge_categorical(self):
  1582. # GH 9426
  1583. right = DataFrame(
  1584. {
  1585. "c": {0: "a", 1: "b", 2: "c", 3: "d", 4: "e"},
  1586. "d": {0: "null", 1: "null", 2: "null", 3: "null", 4: "null"},
  1587. }
  1588. )
  1589. left = DataFrame(
  1590. {
  1591. "a": {0: "f", 1: "f", 2: "f", 3: "f", 4: "f"},
  1592. "b": {0: "g", 1: "g", 2: "g", 3: "g", 4: "g"},
  1593. }
  1594. )
  1595. df = merge(left, right, how="left", left_on="b", right_on="c")
  1596. # object-object
  1597. expected = df.copy()
  1598. # object-cat
  1599. # note that we propagate the category
  1600. # because we don't have any matching rows
  1601. cright = right.copy()
  1602. cright["d"] = cright["d"].astype("category")
  1603. result = merge(left, cright, how="left", left_on="b", right_on="c")
  1604. expected["d"] = expected["d"].astype(CategoricalDtype(["null"]))
  1605. tm.assert_frame_equal(result, expected)
  1606. # cat-object
  1607. cleft = left.copy()
  1608. cleft["b"] = cleft["b"].astype("category")
  1609. result = merge(cleft, cright, how="left", left_on="b", right_on="c")
  1610. tm.assert_frame_equal(result, expected)
  1611. # cat-cat
  1612. cright = right.copy()
  1613. cright["d"] = cright["d"].astype("category")
  1614. cleft = left.copy()
  1615. cleft["b"] = cleft["b"].astype("category")
  1616. result = merge(cleft, cright, how="left", left_on="b", right_on="c")
  1617. tm.assert_frame_equal(result, expected)
  1618. def tests_merge_categorical_unordered_equal(self):
  1619. # GH-19551
  1620. df1 = DataFrame(
  1621. {
  1622. "Foo": Categorical(["A", "B", "C"], categories=["A", "B", "C"]),
  1623. "Left": ["A0", "B0", "C0"],
  1624. }
  1625. )
  1626. df2 = DataFrame(
  1627. {
  1628. "Foo": Categorical(["C", "B", "A"], categories=["C", "B", "A"]),
  1629. "Right": ["C1", "B1", "A1"],
  1630. }
  1631. )
  1632. result = merge(df1, df2, on=["Foo"])
  1633. expected = DataFrame(
  1634. {
  1635. "Foo": Categorical(["A", "B", "C"]),
  1636. "Left": ["A0", "B0", "C0"],
  1637. "Right": ["A1", "B1", "C1"],
  1638. }
  1639. )
  1640. tm.assert_frame_equal(result, expected)
  1641. @pytest.mark.parametrize("ordered", [True, False])
  1642. def test_multiindex_merge_with_unordered_categoricalindex(self, ordered):
  1643. # GH 36973
  1644. pcat = CategoricalDtype(categories=["P2", "P1"], ordered=ordered)
  1645. df1 = DataFrame(
  1646. {
  1647. "id": ["C", "C", "D"],
  1648. "p": Categorical(["P2", "P1", "P2"], dtype=pcat),
  1649. "a": [0, 1, 2],
  1650. }
  1651. ).set_index(["id", "p"])
  1652. df2 = DataFrame(
  1653. {
  1654. "id": ["A", "C", "C"],
  1655. "p": Categorical(["P2", "P2", "P1"], dtype=pcat),
  1656. "d1": [10, 11, 12],
  1657. }
  1658. ).set_index(["id", "p"])
  1659. result = merge(df1, df2, how="left", left_index=True, right_index=True)
  1660. expected = DataFrame(
  1661. {
  1662. "id": ["C", "C", "D"],
  1663. "p": Categorical(["P2", "P1", "P2"], dtype=pcat),
  1664. "a": [0, 1, 2],
  1665. "d1": [11.0, 12.0, np.nan],
  1666. }
  1667. ).set_index(["id", "p"])
  1668. tm.assert_frame_equal(result, expected)
  1669. def test_other_columns(self, left, right):
  1670. # non-merge columns should preserve if possible
  1671. right = right.assign(Z=right.Z.astype("category"))
  1672. merged = merge(left, right, on="X")
  1673. result = merged.dtypes.sort_index()
  1674. expected = Series(
  1675. [
  1676. CategoricalDtype(categories=["foo", "bar"]),
  1677. np.dtype("O"),
  1678. CategoricalDtype(categories=[1, 2]),
  1679. ],
  1680. index=["X", "Y", "Z"],
  1681. )
  1682. tm.assert_series_equal(result, expected)
  1683. # categories are preserved
  1684. assert left.X.values._categories_match_up_to_permutation(merged.X.values)
  1685. assert right.Z.values._categories_match_up_to_permutation(merged.Z.values)
  1686. @pytest.mark.parametrize(
  1687. "change",
  1688. [
  1689. lambda x: x,
  1690. lambda x: x.astype(CDT(["foo", "bar", "bah"])),
  1691. lambda x: x.astype(CDT(ordered=True)),
  1692. ],
  1693. )
  1694. def test_dtype_on_merged_different(self, change, join_type, left, right):
  1695. # our merging columns, X now has 2 different dtypes
  1696. # so we must be object as a result
  1697. X = change(right.X.astype("object"))
  1698. right = right.assign(X=X)
  1699. assert is_categorical_dtype(left.X.values.dtype)
  1700. # assert not left.X.values._categories_match_up_to_permutation(right.X.values)
  1701. merged = merge(left, right, on="X", how=join_type)
  1702. result = merged.dtypes.sort_index()
  1703. expected = Series(
  1704. [np.dtype("O"), np.dtype("O"), np.dtype("int64")], index=["X", "Y", "Z"]
  1705. )
  1706. tm.assert_series_equal(result, expected)
  1707. def test_self_join_multiple_categories(self):
  1708. # GH 16767
  1709. # non-duplicates should work with multiple categories
  1710. m = 5
  1711. df = DataFrame(
  1712. {
  1713. "a": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] * m,
  1714. "b": ["t", "w", "x", "y", "z"] * 2 * m,
  1715. "c": [
  1716. letter
  1717. for each in ["m", "n", "u", "p", "o"]
  1718. for letter in [each] * 2 * m
  1719. ],
  1720. "d": [
  1721. letter
  1722. for each in [
  1723. "aa",
  1724. "bb",
  1725. "cc",
  1726. "dd",
  1727. "ee",
  1728. "ff",
  1729. "gg",
  1730. "hh",
  1731. "ii",
  1732. "jj",
  1733. ]
  1734. for letter in [each] * m
  1735. ],
  1736. }
  1737. )
  1738. # change them all to categorical variables
  1739. df = df.apply(lambda x: x.astype("category"))
  1740. # self-join should equal ourselves
  1741. result = merge(df, df, on=list(df.columns))
  1742. tm.assert_frame_equal(result, df)
  1743. def test_dtype_on_categorical_dates(self):
  1744. # GH 16900
  1745. # dates should not be coerced to ints
  1746. df = DataFrame(
  1747. [[date(2001, 1, 1), 1.1], [date(2001, 1, 2), 1.3]], columns=["date", "num2"]
  1748. )
  1749. df["date"] = df["date"].astype("category")
  1750. df2 = DataFrame(
  1751. [[date(2001, 1, 1), 1.3], [date(2001, 1, 3), 1.4]], columns=["date", "num4"]
  1752. )
  1753. df2["date"] = df2["date"].astype("category")
  1754. expected_outer = DataFrame(
  1755. [
  1756. [pd.Timestamp("2001-01-01").date(), 1.1, 1.3],
  1757. [pd.Timestamp("2001-01-02").date(), 1.3, np.nan],
  1758. [pd.Timestamp("2001-01-03").date(), np.nan, 1.4],
  1759. ],
  1760. columns=["date", "num2", "num4"],
  1761. )
  1762. result_outer = merge(df, df2, how="outer", on=["date"])
  1763. tm.assert_frame_equal(result_outer, expected_outer)
  1764. expected_inner = DataFrame(
  1765. [[pd.Timestamp("2001-01-01").date(), 1.1, 1.3]],
  1766. columns=["date", "num2", "num4"],
  1767. )
  1768. result_inner = merge(df, df2, how="inner", on=["date"])
  1769. tm.assert_frame_equal(result_inner, expected_inner)
  1770. @pytest.mark.parametrize("ordered", [True, False])
  1771. @pytest.mark.parametrize(
  1772. "category_column,categories,expected_categories",
  1773. [
  1774. ([False, True, True, False], [True, False], [True, False]),
  1775. ([2, 1, 1, 2], [1, 2], [1, 2]),
  1776. (["False", "True", "True", "False"], ["True", "False"], ["True", "False"]),
  1777. ],
  1778. )
  1779. def test_merging_with_bool_or_int_cateorical_column(
  1780. self, category_column, categories, expected_categories, ordered
  1781. ):
  1782. # GH 17187
  1783. # merging with a boolean/int categorical column
  1784. df1 = DataFrame({"id": [1, 2, 3, 4], "cat": category_column})
  1785. df1["cat"] = df1["cat"].astype(CDT(categories, ordered=ordered))
  1786. df2 = DataFrame({"id": [2, 4], "num": [1, 9]})
  1787. result = df1.merge(df2)
  1788. expected = DataFrame({"id": [2, 4], "cat": expected_categories, "num": [1, 9]})
  1789. expected["cat"] = expected["cat"].astype(CDT(categories, ordered=ordered))
  1790. tm.assert_frame_equal(expected, result)
  1791. def test_merge_on_int_array(self):
  1792. # GH 23020
  1793. df = DataFrame({"A": Series([1, 2, np.nan], dtype="Int64"), "B": 1})
  1794. result = merge(df, df, on="A")
  1795. expected = DataFrame(
  1796. {"A": Series([1, 2, np.nan], dtype="Int64"), "B_x": 1, "B_y": 1}
  1797. )
  1798. tm.assert_frame_equal(result, expected)
  1799. @pytest.fixture
  1800. def left_df():
  1801. return DataFrame({"a": [20, 10, 0]}, index=[2, 1, 0])
  1802. @pytest.fixture
  1803. def right_df():
  1804. return DataFrame({"b": [300, 100, 200]}, index=[3, 1, 2])
  1805. class TestMergeOnIndexes:
  1806. @pytest.mark.parametrize(
  1807. "how, sort, expected",
  1808. [
  1809. ("inner", False, DataFrame({"a": [20, 10], "b": [200, 100]}, index=[2, 1])),
  1810. ("inner", True, DataFrame({"a": [10, 20], "b": [100, 200]}, index=[1, 2])),
  1811. (
  1812. "left",
  1813. False,
  1814. DataFrame({"a": [20, 10, 0], "b": [200, 100, np.nan]}, index=[2, 1, 0]),
  1815. ),
  1816. (
  1817. "left",
  1818. True,
  1819. DataFrame({"a": [0, 10, 20], "b": [np.nan, 100, 200]}, index=[0, 1, 2]),
  1820. ),
  1821. (
  1822. "right",
  1823. False,
  1824. DataFrame(
  1825. {"a": [np.nan, 10, 20], "b": [300, 100, 200]}, index=[3, 1, 2]
  1826. ),
  1827. ),
  1828. (
  1829. "right",
  1830. True,
  1831. DataFrame(
  1832. {"a": [10, 20, np.nan], "b": [100, 200, 300]}, index=[1, 2, 3]
  1833. ),
  1834. ),
  1835. (
  1836. "outer",
  1837. False,
  1838. DataFrame(
  1839. {"a": [0, 10, 20, np.nan], "b": [np.nan, 100, 200, 300]},
  1840. index=[0, 1, 2, 3],
  1841. ),
  1842. ),
  1843. (
  1844. "outer",
  1845. True,
  1846. DataFrame(
  1847. {"a": [0, 10, 20, np.nan], "b": [np.nan, 100, 200, 300]},
  1848. index=[0, 1, 2, 3],
  1849. ),
  1850. ),
  1851. ],
  1852. )
  1853. def test_merge_on_indexes(self, left_df, right_df, how, sort, expected):
  1854. result = merge(
  1855. left_df, right_df, left_index=True, right_index=True, how=how, sort=sort
  1856. )
  1857. tm.assert_frame_equal(result, expected)
  1858. @pytest.mark.parametrize(
  1859. "index",
  1860. [Index([1, 2], dtype=dtyp, name="index_col") for dtyp in tm.ALL_REAL_NUMPY_DTYPES]
  1861. + [
  1862. CategoricalIndex(["A", "B"], categories=["A", "B"], name="index_col"),
  1863. RangeIndex(start=0, stop=2, name="index_col"),
  1864. DatetimeIndex(["2018-01-01", "2018-01-02"], name="index_col"),
  1865. ],
  1866. ids=lambda x: f"{type(x).__name__}[{x.dtype}]",
  1867. )
  1868. def test_merge_index_types(index):
  1869. # gh-20777
  1870. # assert key access is consistent across index types
  1871. left = DataFrame({"left_data": [1, 2]}, index=index)
  1872. right = DataFrame({"right_data": [1.0, 2.0]}, index=index)
  1873. result = left.merge(right, on=["index_col"])
  1874. expected = DataFrame({"left_data": [1, 2], "right_data": [1.0, 2.0]}, index=index)
  1875. tm.assert_frame_equal(result, expected)
  1876. @pytest.mark.parametrize(
  1877. "on,left_on,right_on,left_index,right_index,nm",
  1878. [
  1879. (["outer", "inner"], None, None, False, False, "B"),
  1880. (None, None, None, True, True, "B"),
  1881. (None, ["outer", "inner"], None, False, True, "B"),
  1882. (None, None, ["outer", "inner"], True, False, "B"),
  1883. (["outer", "inner"], None, None, False, False, None),
  1884. (None, None, None, True, True, None),
  1885. (None, ["outer", "inner"], None, False, True, None),
  1886. (None, None, ["outer", "inner"], True, False, None),
  1887. ],
  1888. )
  1889. def test_merge_series(on, left_on, right_on, left_index, right_index, nm):
  1890. # GH 21220
  1891. a = DataFrame(
  1892. {"A": [1, 2, 3, 4]},
  1893. index=MultiIndex.from_product([["a", "b"], [0, 1]], names=["outer", "inner"]),
  1894. )
  1895. b = Series(
  1896. [1, 2, 3, 4],
  1897. index=MultiIndex.from_product([["a", "b"], [1, 2]], names=["outer", "inner"]),
  1898. name=nm,
  1899. )
  1900. expected = DataFrame(
  1901. {"A": [2, 4], "B": [1, 3]},
  1902. index=MultiIndex.from_product([["a", "b"], [1]], names=["outer", "inner"]),
  1903. )
  1904. if nm is not None:
  1905. result = merge(
  1906. a,
  1907. b,
  1908. on=on,
  1909. left_on=left_on,
  1910. right_on=right_on,
  1911. left_index=left_index,
  1912. right_index=right_index,
  1913. )
  1914. tm.assert_frame_equal(result, expected)
  1915. else:
  1916. msg = "Cannot merge a Series without a name"
  1917. with pytest.raises(ValueError, match=msg):
  1918. result = merge(
  1919. a,
  1920. b,
  1921. on=on,
  1922. left_on=left_on,
  1923. right_on=right_on,
  1924. left_index=left_index,
  1925. right_index=right_index,
  1926. )
  1927. def test_merge_series_multilevel():
  1928. # GH#47946
  1929. # GH 40993: For raising, enforced in 2.0
  1930. a = DataFrame(
  1931. {"A": [1, 2, 3, 4]},
  1932. index=MultiIndex.from_product([["a", "b"], [0, 1]], names=["outer", "inner"]),
  1933. )
  1934. b = Series(
  1935. [1, 2, 3, 4],
  1936. index=MultiIndex.from_product([["a", "b"], [1, 2]], names=["outer", "inner"]),
  1937. name=("B", "C"),
  1938. )
  1939. with pytest.raises(
  1940. MergeError, match="Not allowed to merge between different levels"
  1941. ):
  1942. merge(a, b, on=["outer", "inner"])
  1943. @pytest.mark.parametrize(
  1944. "col1, col2, kwargs, expected_cols",
  1945. [
  1946. (0, 0, {"suffixes": ("", "_dup")}, ["0", "0_dup"]),
  1947. (0, 0, {"suffixes": (None, "_dup")}, [0, "0_dup"]),
  1948. (0, 0, {"suffixes": ("_x", "_y")}, ["0_x", "0_y"]),
  1949. (0, 0, {"suffixes": ["_x", "_y"]}, ["0_x", "0_y"]),
  1950. ("a", 0, {"suffixes": (None, "_y")}, ["a", 0]),
  1951. (0.0, 0.0, {"suffixes": ("_x", None)}, ["0.0_x", 0.0]),
  1952. ("b", "b", {"suffixes": (None, "_y")}, ["b", "b_y"]),
  1953. ("a", "a", {"suffixes": ("_x", None)}, ["a_x", "a"]),
  1954. ("a", "b", {"suffixes": ("_x", None)}, ["a", "b"]),
  1955. ("a", "a", {"suffixes": (None, "_x")}, ["a", "a_x"]),
  1956. (0, 0, {"suffixes": ("_a", None)}, ["0_a", 0]),
  1957. ("a", "a", {}, ["a_x", "a_y"]),
  1958. (0, 0, {}, ["0_x", "0_y"]),
  1959. ],
  1960. )
  1961. def test_merge_suffix(col1, col2, kwargs, expected_cols):
  1962. # issue: 24782
  1963. a = DataFrame({col1: [1, 2, 3]})
  1964. b = DataFrame({col2: [4, 5, 6]})
  1965. expected = DataFrame([[1, 4], [2, 5], [3, 6]], columns=expected_cols)
  1966. result = a.merge(b, left_index=True, right_index=True, **kwargs)
  1967. tm.assert_frame_equal(result, expected)
  1968. result = merge(a, b, left_index=True, right_index=True, **kwargs)
  1969. tm.assert_frame_equal(result, expected)
  1970. @pytest.mark.parametrize(
  1971. "how,expected",
  1972. [
  1973. (
  1974. "right",
  1975. DataFrame(
  1976. {"A": [100, 200, 300], "B1": [60, 70, np.nan], "B2": [600, 700, 800]}
  1977. ),
  1978. ),
  1979. (
  1980. "outer",
  1981. DataFrame(
  1982. {
  1983. "A": [100, 200, 1, 300],
  1984. "B1": [60, 70, 80, np.nan],
  1985. "B2": [600, 700, np.nan, 800],
  1986. }
  1987. ),
  1988. ),
  1989. ],
  1990. )
  1991. def test_merge_duplicate_suffix(how, expected):
  1992. left_df = DataFrame({"A": [100, 200, 1], "B": [60, 70, 80]})
  1993. right_df = DataFrame({"A": [100, 200, 300], "B": [600, 700, 800]})
  1994. result = merge(left_df, right_df, on="A", how=how, suffixes=("_x", "_x"))
  1995. expected.columns = ["A", "B_x", "B_x"]
  1996. tm.assert_frame_equal(result, expected)
  1997. @pytest.mark.parametrize(
  1998. "col1, col2, suffixes",
  1999. [("a", "a", (None, None)), ("a", "a", ("", None)), (0, 0, (None, ""))],
  2000. )
  2001. def test_merge_suffix_error(col1, col2, suffixes):
  2002. # issue: 24782
  2003. a = DataFrame({col1: [1, 2, 3]})
  2004. b = DataFrame({col2: [3, 4, 5]})
  2005. # TODO: might reconsider current raise behaviour, see issue 24782
  2006. msg = "columns overlap but no suffix specified"
  2007. with pytest.raises(ValueError, match=msg):
  2008. merge(a, b, left_index=True, right_index=True, suffixes=suffixes)
  2009. @pytest.mark.parametrize("suffixes", [{"left", "right"}, {"left": 0, "right": 0}])
  2010. def test_merge_suffix_raises(suffixes):
  2011. a = DataFrame({"a": [1, 2, 3]})
  2012. b = DataFrame({"b": [3, 4, 5]})
  2013. with pytest.raises(TypeError, match="Passing 'suffixes' as a"):
  2014. merge(a, b, left_index=True, right_index=True, suffixes=suffixes)
  2015. @pytest.mark.parametrize(
  2016. "col1, col2, suffixes, msg",
  2017. [
  2018. ("a", "a", ("a", "b", "c"), r"too many values to unpack \(expected 2\)"),
  2019. ("a", "a", tuple("a"), r"not enough values to unpack \(expected 2, got 1\)"),
  2020. ],
  2021. )
  2022. def test_merge_suffix_length_error(col1, col2, suffixes, msg):
  2023. a = DataFrame({col1: [1, 2, 3]})
  2024. b = DataFrame({col2: [3, 4, 5]})
  2025. with pytest.raises(ValueError, match=msg):
  2026. merge(a, b, left_index=True, right_index=True, suffixes=suffixes)
  2027. @pytest.mark.parametrize("cat_dtype", ["one", "two"])
  2028. @pytest.mark.parametrize("reverse", [True, False])
  2029. def test_merge_equal_cat_dtypes(cat_dtype, reverse):
  2030. # see gh-22501
  2031. cat_dtypes = {
  2032. "one": CategoricalDtype(categories=["a", "b", "c"], ordered=False),
  2033. "two": CategoricalDtype(categories=["a", "b", "c"], ordered=False),
  2034. }
  2035. df1 = DataFrame(
  2036. {"foo": Series(["a", "b", "c"]).astype(cat_dtypes["one"]), "left": [1, 2, 3]}
  2037. ).set_index("foo")
  2038. data_foo = ["a", "b", "c"]
  2039. data_right = [1, 2, 3]
  2040. if reverse:
  2041. data_foo.reverse()
  2042. data_right.reverse()
  2043. df2 = DataFrame(
  2044. {"foo": Series(data_foo).astype(cat_dtypes[cat_dtype]), "right": data_right}
  2045. ).set_index("foo")
  2046. result = df1.merge(df2, left_index=True, right_index=True)
  2047. expected = DataFrame(
  2048. {
  2049. "left": [1, 2, 3],
  2050. "right": [1, 2, 3],
  2051. "foo": Series(["a", "b", "c"]).astype(cat_dtypes["one"]),
  2052. }
  2053. ).set_index("foo")
  2054. tm.assert_frame_equal(result, expected)
  2055. def test_merge_equal_cat_dtypes2():
  2056. # see gh-22501
  2057. cat_dtype = CategoricalDtype(categories=["a", "b", "c"], ordered=False)
  2058. # Test Data
  2059. df1 = DataFrame(
  2060. {"foo": Series(["a", "b"]).astype(cat_dtype), "left": [1, 2]}
  2061. ).set_index("foo")
  2062. df2 = DataFrame(
  2063. {"foo": Series(["a", "b", "c"]).astype(cat_dtype), "right": [3, 2, 1]}
  2064. ).set_index("foo")
  2065. result = df1.merge(df2, left_index=True, right_index=True)
  2066. expected = DataFrame(
  2067. {"left": [1, 2], "right": [3, 2], "foo": Series(["a", "b"]).astype(cat_dtype)}
  2068. ).set_index("foo")
  2069. tm.assert_frame_equal(result, expected)
  2070. def test_merge_on_cat_and_ext_array():
  2071. # GH 28668
  2072. right = DataFrame(
  2073. {"a": Series([pd.Interval(0, 1), pd.Interval(1, 2)], dtype="interval")}
  2074. )
  2075. left = right.copy()
  2076. left["a"] = left["a"].astype("category")
  2077. result = merge(left, right, how="inner", on="a")
  2078. expected = right.copy()
  2079. tm.assert_frame_equal(result, expected)
  2080. def test_merge_multiindex_columns():
  2081. # Issue #28518
  2082. # Verify that merging two dataframes give the expected labels
  2083. # The original cause of this issue come from a bug lexsort_depth and is tested in
  2084. # test_lexsort_depth
  2085. letters = ["a", "b", "c", "d"]
  2086. numbers = ["1", "2", "3"]
  2087. index = MultiIndex.from_product((letters, numbers), names=["outer", "inner"])
  2088. frame_x = DataFrame(columns=index)
  2089. frame_x["id"] = ""
  2090. frame_y = DataFrame(columns=index)
  2091. frame_y["id"] = ""
  2092. l_suf = "_x"
  2093. r_suf = "_y"
  2094. result = frame_x.merge(frame_y, on="id", suffixes=((l_suf, r_suf)))
  2095. # Constructing the expected results
  2096. expected_labels = [letter + l_suf for letter in letters] + [
  2097. letter + r_suf for letter in letters
  2098. ]
  2099. expected_index = MultiIndex.from_product(
  2100. [expected_labels, numbers], names=["outer", "inner"]
  2101. )
  2102. expected = DataFrame(columns=expected_index)
  2103. expected["id"] = ""
  2104. tm.assert_frame_equal(result, expected)
  2105. def test_merge_datetime_upcast_dtype():
  2106. # https://github.com/pandas-dev/pandas/issues/31208
  2107. df1 = DataFrame({"x": ["a", "b", "c"], "y": ["1", "2", "4"]})
  2108. df2 = DataFrame(
  2109. {"y": ["1", "2", "3"], "z": pd.to_datetime(["2000", "2001", "2002"])}
  2110. )
  2111. result = merge(df1, df2, how="left", on="y")
  2112. expected = DataFrame(
  2113. {
  2114. "x": ["a", "b", "c"],
  2115. "y": ["1", "2", "4"],
  2116. "z": pd.to_datetime(["2000", "2001", "NaT"]),
  2117. }
  2118. )
  2119. tm.assert_frame_equal(result, expected)
  2120. @pytest.mark.parametrize("n_categories", [5, 128])
  2121. def test_categorical_non_unique_monotonic(n_categories):
  2122. # GH 28189
  2123. # With n_categories as 5, we test the int8 case is hit in libjoin,
  2124. # with n_categories as 128 we test the int16 case.
  2125. left_index = CategoricalIndex([0] + list(range(n_categories)))
  2126. df1 = DataFrame(range(n_categories + 1), columns=["value"], index=left_index)
  2127. df2 = DataFrame(
  2128. [[6]],
  2129. columns=["value"],
  2130. index=CategoricalIndex([0], categories=list(range(n_categories))),
  2131. )
  2132. result = merge(df1, df2, how="left", left_index=True, right_index=True)
  2133. expected = DataFrame(
  2134. [[i, 6.0] if i < 2 else [i, np.nan] for i in range(n_categories + 1)],
  2135. columns=["value_x", "value_y"],
  2136. index=left_index,
  2137. )
  2138. tm.assert_frame_equal(expected, result)
  2139. def test_merge_join_categorical_multiindex():
  2140. # From issue 16627
  2141. a = {
  2142. "Cat1": Categorical(["a", "b", "a", "c", "a", "b"], ["a", "b", "c"]),
  2143. "Int1": [0, 1, 0, 1, 0, 0],
  2144. }
  2145. a = DataFrame(a)
  2146. b = {
  2147. "Cat": Categorical(["a", "b", "c", "a", "b", "c"], ["a", "b", "c"]),
  2148. "Int": [0, 0, 0, 1, 1, 1],
  2149. "Factor": [1.1, 1.2, 1.3, 1.4, 1.5, 1.6],
  2150. }
  2151. b = DataFrame(b).set_index(["Cat", "Int"])["Factor"]
  2152. expected = merge(
  2153. a,
  2154. b.reset_index(),
  2155. left_on=["Cat1", "Int1"],
  2156. right_on=["Cat", "Int"],
  2157. how="left",
  2158. )
  2159. expected = expected.drop(["Cat", "Int"], axis=1)
  2160. result = a.join(b, on=["Cat1", "Int1"])
  2161. tm.assert_frame_equal(expected, result)
  2162. # Same test, but with ordered categorical
  2163. a = {
  2164. "Cat1": Categorical(
  2165. ["a", "b", "a", "c", "a", "b"], ["b", "a", "c"], ordered=True
  2166. ),
  2167. "Int1": [0, 1, 0, 1, 0, 0],
  2168. }
  2169. a = DataFrame(a)
  2170. b = {
  2171. "Cat": Categorical(
  2172. ["a", "b", "c", "a", "b", "c"], ["b", "a", "c"], ordered=True
  2173. ),
  2174. "Int": [0, 0, 0, 1, 1, 1],
  2175. "Factor": [1.1, 1.2, 1.3, 1.4, 1.5, 1.6],
  2176. }
  2177. b = DataFrame(b).set_index(["Cat", "Int"])["Factor"]
  2178. expected = merge(
  2179. a,
  2180. b.reset_index(),
  2181. left_on=["Cat1", "Int1"],
  2182. right_on=["Cat", "Int"],
  2183. how="left",
  2184. )
  2185. expected = expected.drop(["Cat", "Int"], axis=1)
  2186. result = a.join(b, on=["Cat1", "Int1"])
  2187. tm.assert_frame_equal(expected, result)
  2188. @pytest.mark.parametrize("func", ["merge", "merge_asof"])
  2189. @pytest.mark.parametrize(
  2190. ("kwargs", "err_msg"),
  2191. [
  2192. ({"left_on": "a", "left_index": True}, ["left_on", "left_index"]),
  2193. ({"right_on": "a", "right_index": True}, ["right_on", "right_index"]),
  2194. ],
  2195. )
  2196. def test_merge_join_cols_error_reporting_duplicates(func, kwargs, err_msg):
  2197. # GH: 16228
  2198. left = DataFrame({"a": [1, 2], "b": [3, 4]})
  2199. right = DataFrame({"a": [1, 1], "c": [5, 6]})
  2200. msg = rf'Can only pass argument "{err_msg[0]}" OR "{err_msg[1]}" not both\.'
  2201. with pytest.raises(MergeError, match=msg):
  2202. getattr(pd, func)(left, right, **kwargs)
  2203. @pytest.mark.parametrize("func", ["merge", "merge_asof"])
  2204. @pytest.mark.parametrize(
  2205. ("kwargs", "err_msg"),
  2206. [
  2207. ({"left_on": "a"}, ["right_on", "right_index"]),
  2208. ({"right_on": "a"}, ["left_on", "left_index"]),
  2209. ],
  2210. )
  2211. def test_merge_join_cols_error_reporting_missing(func, kwargs, err_msg):
  2212. # GH: 16228
  2213. left = DataFrame({"a": [1, 2], "b": [3, 4]})
  2214. right = DataFrame({"a": [1, 1], "c": [5, 6]})
  2215. msg = rf'Must pass "{err_msg[0]}" OR "{err_msg[1]}"\.'
  2216. with pytest.raises(MergeError, match=msg):
  2217. getattr(pd, func)(left, right, **kwargs)
  2218. @pytest.mark.parametrize("func", ["merge", "merge_asof"])
  2219. @pytest.mark.parametrize(
  2220. "kwargs",
  2221. [
  2222. {"right_index": True},
  2223. {"left_index": True},
  2224. ],
  2225. )
  2226. def test_merge_join_cols_error_reporting_on_and_index(func, kwargs):
  2227. # GH: 16228
  2228. left = DataFrame({"a": [1, 2], "b": [3, 4]})
  2229. right = DataFrame({"a": [1, 1], "c": [5, 6]})
  2230. msg = (
  2231. r'Can only pass argument "on" OR "left_index" '
  2232. r'and "right_index", not a combination of both\.'
  2233. )
  2234. with pytest.raises(MergeError, match=msg):
  2235. getattr(pd, func)(left, right, on="a", **kwargs)
  2236. def test_merge_right_left_index():
  2237. # GH#38616
  2238. left = DataFrame({"x": [1, 1], "z": ["foo", "foo"]})
  2239. right = DataFrame({"x": [1, 1], "z": ["foo", "foo"]})
  2240. result = merge(left, right, how="right", left_index=True, right_on="x")
  2241. expected = DataFrame(
  2242. {
  2243. "x": [1, 1],
  2244. "x_x": [1, 1],
  2245. "z_x": ["foo", "foo"],
  2246. "x_y": [1, 1],
  2247. "z_y": ["foo", "foo"],
  2248. }
  2249. )
  2250. tm.assert_frame_equal(result, expected)
  2251. def test_merge_result_empty_index_and_on():
  2252. # GH#33814
  2253. df1 = DataFrame({"a": [1], "b": [2]}).set_index(["a", "b"])
  2254. df2 = DataFrame({"b": [1]}).set_index(["b"])
  2255. expected = DataFrame({"a": [], "b": []}, dtype=np.int64).set_index(["a", "b"])
  2256. result = merge(df1, df2, left_on=["b"], right_index=True)
  2257. tm.assert_frame_equal(result, expected)
  2258. result = merge(df2, df1, left_index=True, right_on=["b"])
  2259. tm.assert_frame_equal(result, expected)
  2260. def test_merge_suffixes_produce_dup_columns_raises():
  2261. # GH#22818; Enforced in 2.0
  2262. left = DataFrame({"a": [1, 2, 3], "b": 1, "b_x": 2})
  2263. right = DataFrame({"a": [1, 2, 3], "b": 2})
  2264. with pytest.raises(MergeError, match="Passing 'suffixes' which cause duplicate"):
  2265. merge(left, right, on="a")
  2266. with pytest.raises(MergeError, match="Passing 'suffixes' which cause duplicate"):
  2267. merge(right, left, on="a", suffixes=("_y", "_x"))
  2268. def test_merge_duplicate_columns_with_suffix_no_warning():
  2269. # GH#22818
  2270. # Do not raise warning when duplicates are caused by duplicates in origin
  2271. left = DataFrame([[1, 1, 1], [2, 2, 2]], columns=["a", "b", "b"])
  2272. right = DataFrame({"a": [1, 3], "b": 2})
  2273. result = merge(left, right, on="a")
  2274. expected = DataFrame([[1, 1, 1, 2]], columns=["a", "b_x", "b_x", "b_y"])
  2275. tm.assert_frame_equal(result, expected)
  2276. def test_merge_duplicate_columns_with_suffix_causing_another_duplicate_raises():
  2277. # GH#22818, Enforced in 2.0
  2278. # This should raise warning because suffixes cause another collision
  2279. left = DataFrame([[1, 1, 1, 1], [2, 2, 2, 2]], columns=["a", "b", "b", "b_x"])
  2280. right = DataFrame({"a": [1, 3], "b": 2})
  2281. with pytest.raises(MergeError, match="Passing 'suffixes' which cause duplicate"):
  2282. merge(left, right, on="a")
  2283. def test_merge_string_float_column_result():
  2284. # GH 13353
  2285. df1 = DataFrame([[1, 2], [3, 4]], columns=Index(["a", 114.0]))
  2286. df2 = DataFrame([[9, 10], [11, 12]], columns=["x", "y"])
  2287. result = merge(df2, df1, how="inner", left_index=True, right_index=True)
  2288. expected = DataFrame(
  2289. [[9, 10, 1, 2], [11, 12, 3, 4]], columns=Index(["x", "y", "a", 114.0])
  2290. )
  2291. tm.assert_frame_equal(result, expected)
  2292. def test_mergeerror_on_left_index_mismatched_dtypes():
  2293. # GH 22449
  2294. df_1 = DataFrame(data=["X"], columns=["C"], index=[22])
  2295. df_2 = DataFrame(data=["X"], columns=["C"], index=[999])
  2296. with pytest.raises(MergeError, match="Can only pass argument"):
  2297. merge(df_1, df_2, on=["C"], left_index=True)
  2298. def test_merge_on_left_categoricalindex():
  2299. # GH#48464 don't raise when left_on is a CategoricalIndex
  2300. ci = CategoricalIndex(range(3))
  2301. right = DataFrame({"A": ci, "B": range(3)})
  2302. left = DataFrame({"C": range(3, 6)})
  2303. res = merge(left, right, left_on=ci, right_on="A")
  2304. expected = merge(left, right, left_on=ci._data, right_on="A")
  2305. tm.assert_frame_equal(res, expected)
  2306. @pytest.mark.parametrize("dtype", [None, "Int64"])
  2307. def test_merge_outer_with_NaN(dtype):
  2308. # GH#43550
  2309. left = DataFrame({"key": [1, 2], "col1": [1, 2]}, dtype=dtype)
  2310. right = DataFrame({"key": [np.nan, np.nan], "col2": [3, 4]}, dtype=dtype)
  2311. result = merge(left, right, on="key", how="outer")
  2312. expected = DataFrame(
  2313. {
  2314. "key": [1, 2, np.nan, np.nan],
  2315. "col1": [1, 2, np.nan, np.nan],
  2316. "col2": [np.nan, np.nan, 3, 4],
  2317. },
  2318. dtype=dtype,
  2319. )
  2320. tm.assert_frame_equal(result, expected)
  2321. # switch left and right
  2322. result = merge(right, left, on="key", how="outer")
  2323. expected = DataFrame(
  2324. {
  2325. "key": [np.nan, np.nan, 1, 2],
  2326. "col2": [3, 4, np.nan, np.nan],
  2327. "col1": [np.nan, np.nan, 1, 2],
  2328. },
  2329. dtype=dtype,
  2330. )
  2331. tm.assert_frame_equal(result, expected)
  2332. def test_merge_different_index_names():
  2333. # GH#45094
  2334. left = DataFrame({"a": [1]}, index=Index([1], name="c"))
  2335. right = DataFrame({"a": [1]}, index=Index([1], name="d"))
  2336. result = merge(left, right, left_on="c", right_on="d")
  2337. expected = DataFrame({"a_x": [1], "a_y": 1})
  2338. tm.assert_frame_equal(result, expected)
  2339. def test_merge_ea(any_numeric_ea_dtype, join_type):
  2340. # GH#44240
  2341. left = DataFrame({"a": [1, 2, 3], "b": 1}, dtype=any_numeric_ea_dtype)
  2342. right = DataFrame({"a": [1, 2, 3], "c": 2}, dtype=any_numeric_ea_dtype)
  2343. result = left.merge(right, how=join_type)
  2344. expected = DataFrame({"a": [1, 2, 3], "b": 1, "c": 2}, dtype=any_numeric_ea_dtype)
  2345. tm.assert_frame_equal(result, expected)
  2346. def test_merge_ea_and_non_ea(any_numeric_ea_dtype, join_type):
  2347. # GH#44240
  2348. left = DataFrame({"a": [1, 2, 3], "b": 1}, dtype=any_numeric_ea_dtype)
  2349. right = DataFrame({"a": [1, 2, 3], "c": 2}, dtype=any_numeric_ea_dtype.lower())
  2350. result = left.merge(right, how=join_type)
  2351. expected = DataFrame(
  2352. {
  2353. "a": Series([1, 2, 3], dtype=any_numeric_ea_dtype),
  2354. "b": Series([1, 1, 1], dtype=any_numeric_ea_dtype),
  2355. "c": Series([2, 2, 2], dtype=any_numeric_ea_dtype.lower()),
  2356. }
  2357. )
  2358. tm.assert_frame_equal(result, expected)
  2359. @pytest.mark.parametrize("dtype", ["int64", "int64[pyarrow]"])
  2360. def test_merge_arrow_and_numpy_dtypes(dtype):
  2361. # GH#52406
  2362. pytest.importorskip("pyarrow")
  2363. df = DataFrame({"a": [1, 2]}, dtype=dtype)
  2364. df2 = DataFrame({"a": [1, 2]}, dtype="int64[pyarrow]")
  2365. result = df.merge(df2)
  2366. expected = df.copy()
  2367. tm.assert_frame_equal(result, expected)
  2368. result = df2.merge(df)
  2369. expected = df2.copy()
  2370. tm.assert_frame_equal(result, expected)
  2371. @pytest.mark.parametrize("how", ["inner", "left", "outer", "right"])
  2372. @pytest.mark.parametrize("tz", [None, "America/Chicago"])
  2373. def test_merge_datetime_different_resolution(tz, how):
  2374. # https://github.com/pandas-dev/pandas/issues/53200
  2375. vals = [
  2376. pd.Timestamp(2023, 5, 12, tz=tz),
  2377. pd.Timestamp(2023, 5, 13, tz=tz),
  2378. pd.Timestamp(2023, 5, 14, tz=tz),
  2379. ]
  2380. df1 = DataFrame({"t": vals[:2], "a": [1.0, 2.0]})
  2381. df1["t"] = df1["t"].dt.as_unit("ns")
  2382. df2 = DataFrame({"t": vals[1:], "b": [1.0, 2.0]})
  2383. df2["t"] = df2["t"].dt.as_unit("s")
  2384. expected = DataFrame({"t": vals, "a": [1.0, 2.0, np.nan], "b": [np.nan, 1.0, 2.0]})
  2385. expected["t"] = expected["t"].dt.as_unit("ns")
  2386. if how == "inner":
  2387. expected = expected.iloc[[1]].reset_index(drop=True)
  2388. elif how == "left":
  2389. expected = expected.iloc[[0, 1]]
  2390. elif how == "right":
  2391. expected = expected.iloc[[1, 2]].reset_index(drop=True)
  2392. result = df1.merge(df2, on="t", how=how)
  2393. tm.assert_frame_equal(result, expected)