test_numeric.py 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. from datetime import datetime, timedelta
  2. import re
  3. import numpy as np
  4. import pytest
  5. from pandas._libs.tslibs import Timestamp
  6. import pandas as pd
  7. from pandas import Float64Index, Index, Int64Index, Series, UInt64Index
  8. import pandas._testing as tm
  9. from pandas.api.types import pandas_dtype
  10. from pandas.tests.indexes.common import Base
  11. class Numeric(Base):
  12. def test_can_hold_identifiers(self):
  13. idx = self.create_index()
  14. key = idx[0]
  15. assert idx._can_hold_identifiers_and_holds_name(key) is False
  16. def test_numeric_compat(self):
  17. pass # override Base method
  18. def test_explicit_conversions(self):
  19. # GH 8608
  20. # add/sub are overridden explicitly for Float/Int Index
  21. idx = self._holder(np.arange(5, dtype="int64"))
  22. # float conversions
  23. arr = np.arange(5, dtype="int64") * 3.2
  24. expected = Float64Index(arr)
  25. fidx = idx * 3.2
  26. tm.assert_index_equal(fidx, expected)
  27. fidx = 3.2 * idx
  28. tm.assert_index_equal(fidx, expected)
  29. # interops with numpy arrays
  30. expected = Float64Index(arr)
  31. a = np.zeros(5, dtype="float64")
  32. result = fidx - a
  33. tm.assert_index_equal(result, expected)
  34. expected = Float64Index(-arr)
  35. a = np.zeros(5, dtype="float64")
  36. result = a - fidx
  37. tm.assert_index_equal(result, expected)
  38. def test_index_groupby(self):
  39. int_idx = Index(range(6))
  40. float_idx = Index(np.arange(0, 0.6, 0.1))
  41. obj_idx = Index("A B C D E F".split())
  42. dt_idx = pd.date_range("2013-01-01", freq="M", periods=6)
  43. for idx in [int_idx, float_idx, obj_idx, dt_idx]:
  44. to_groupby = np.array([1, 2, np.nan, np.nan, 2, 1])
  45. tm.assert_dict_equal(
  46. idx.groupby(to_groupby), {1.0: idx[[0, 5]], 2.0: idx[[1, 4]]}
  47. )
  48. to_groupby = Index(
  49. [
  50. datetime(2011, 11, 1),
  51. datetime(2011, 12, 1),
  52. pd.NaT,
  53. pd.NaT,
  54. datetime(2011, 12, 1),
  55. datetime(2011, 11, 1),
  56. ],
  57. tz="UTC",
  58. ).values
  59. ex_keys = [Timestamp("2011-11-01"), Timestamp("2011-12-01")]
  60. expected = {ex_keys[0]: idx[[0, 5]], ex_keys[1]: idx[[1, 4]]}
  61. tm.assert_dict_equal(idx.groupby(to_groupby), expected)
  62. @pytest.mark.parametrize("klass", [list, tuple, np.array, Series])
  63. def test_where(self, klass):
  64. i = self.create_index()
  65. cond = [True] * len(i)
  66. expected = i
  67. result = i.where(klass(cond))
  68. cond = [False] + [True] * (len(i) - 1)
  69. expected = Float64Index([i._na_value] + i[1:].tolist())
  70. result = i.where(klass(cond))
  71. tm.assert_index_equal(result, expected)
  72. def test_insert(self, nulls_fixture):
  73. # GH 18295 (test missing)
  74. index = self.create_index()
  75. expected = Float64Index([index[0], np.nan] + list(index[1:]))
  76. result = index.insert(1, nulls_fixture)
  77. tm.assert_index_equal(result, expected)
  78. class TestFloat64Index(Numeric):
  79. _holder = Float64Index
  80. @pytest.fixture(
  81. params=[
  82. [1.5, 2, 3, 4, 5],
  83. [0.0, 2.5, 5.0, 7.5, 10.0],
  84. [5, 4, 3, 2, 1.5],
  85. [10.0, 7.5, 5.0, 2.5, 0.0],
  86. ],
  87. ids=["mixed", "float", "mixed_dec", "float_dec"],
  88. )
  89. def indices(self, request):
  90. return Float64Index(request.param)
  91. @pytest.fixture
  92. def mixed_index(self):
  93. return Float64Index([1.5, 2, 3, 4, 5])
  94. @pytest.fixture
  95. def float_index(self):
  96. return Float64Index([0.0, 2.5, 5.0, 7.5, 10.0])
  97. def create_index(self):
  98. return Float64Index(np.arange(5, dtype="float64"))
  99. def test_repr_roundtrip(self, indices):
  100. tm.assert_index_equal(eval(repr(indices)), indices)
  101. def check_is_index(self, i):
  102. assert isinstance(i, Index)
  103. assert not isinstance(i, Float64Index)
  104. def check_coerce(self, a, b, is_float_index=True):
  105. assert a.equals(b)
  106. tm.assert_index_equal(a, b, exact=False)
  107. if is_float_index:
  108. assert isinstance(b, Float64Index)
  109. else:
  110. self.check_is_index(b)
  111. def test_constructor(self):
  112. # explicit construction
  113. index = Float64Index([1, 2, 3, 4, 5])
  114. assert isinstance(index, Float64Index)
  115. expected = np.array([1, 2, 3, 4, 5], dtype="float64")
  116. tm.assert_numpy_array_equal(index.values, expected)
  117. index = Float64Index(np.array([1, 2, 3, 4, 5]))
  118. assert isinstance(index, Float64Index)
  119. index = Float64Index([1.0, 2, 3, 4, 5])
  120. assert isinstance(index, Float64Index)
  121. index = Float64Index(np.array([1.0, 2, 3, 4, 5]))
  122. assert isinstance(index, Float64Index)
  123. assert index.dtype == float
  124. index = Float64Index(np.array([1.0, 2, 3, 4, 5]), dtype=np.float32)
  125. assert isinstance(index, Float64Index)
  126. assert index.dtype == np.float64
  127. index = Float64Index(np.array([1, 2, 3, 4, 5]), dtype=np.float32)
  128. assert isinstance(index, Float64Index)
  129. assert index.dtype == np.float64
  130. # nan handling
  131. result = Float64Index([np.nan, np.nan])
  132. assert pd.isna(result.values).all()
  133. result = Float64Index(np.array([np.nan]))
  134. assert pd.isna(result.values).all()
  135. result = Index(np.array([np.nan]))
  136. assert pd.isna(result.values).all()
  137. @pytest.mark.parametrize(
  138. "index, dtype",
  139. [
  140. (pd.Int64Index, "float64"),
  141. (pd.UInt64Index, "categorical"),
  142. (pd.Float64Index, "datetime64"),
  143. (pd.RangeIndex, "float64"),
  144. ],
  145. )
  146. def test_invalid_dtype(self, index, dtype):
  147. # GH 29539
  148. with pytest.raises(
  149. ValueError,
  150. match=rf"Incorrect `dtype` passed: expected \w+(?: \w+)?, received {dtype}",
  151. ):
  152. index([1, 2, 3], dtype=dtype)
  153. def test_constructor_invalid(self):
  154. # invalid
  155. msg = (
  156. r"Float64Index\(\.\.\.\) must be called with a collection of"
  157. r" some kind, 0\.0 was passed"
  158. )
  159. with pytest.raises(TypeError, match=msg):
  160. Float64Index(0.0)
  161. msg = (
  162. "String dtype not supported, "
  163. "you may need to explicitly cast to a numeric type"
  164. )
  165. with pytest.raises(TypeError, match=msg):
  166. Float64Index(["a", "b", 0.0])
  167. msg = r"float\(\) argument must be a string or a number, not 'Timestamp'"
  168. with pytest.raises(TypeError, match=msg):
  169. Float64Index([Timestamp("20130101")])
  170. def test_constructor_coerce(self, mixed_index, float_index):
  171. self.check_coerce(mixed_index, Index([1.5, 2, 3, 4, 5]))
  172. self.check_coerce(float_index, Index(np.arange(5) * 2.5))
  173. self.check_coerce(
  174. float_index, Index(np.array(np.arange(5) * 2.5, dtype=object))
  175. )
  176. def test_constructor_explicit(self, mixed_index, float_index):
  177. # these don't auto convert
  178. self.check_coerce(
  179. float_index, Index((np.arange(5) * 2.5), dtype=object), is_float_index=False
  180. )
  181. self.check_coerce(
  182. mixed_index, Index([1.5, 2, 3, 4, 5], dtype=object), is_float_index=False
  183. )
  184. def test_astype(self, mixed_index, float_index):
  185. result = float_index.astype(object)
  186. assert result.equals(float_index)
  187. assert float_index.equals(result)
  188. self.check_is_index(result)
  189. i = mixed_index.copy()
  190. i.name = "foo"
  191. result = i.astype(object)
  192. assert result.equals(i)
  193. assert i.equals(result)
  194. self.check_is_index(result)
  195. # GH 12881
  196. # a float astype int
  197. for dtype in ["int16", "int32", "int64"]:
  198. i = Float64Index([0, 1, 2])
  199. result = i.astype(dtype)
  200. expected = Int64Index([0, 1, 2])
  201. tm.assert_index_equal(result, expected)
  202. i = Float64Index([0, 1.1, 2])
  203. result = i.astype(dtype)
  204. expected = Int64Index([0, 1, 2])
  205. tm.assert_index_equal(result, expected)
  206. for dtype in ["float32", "float64"]:
  207. i = Float64Index([0, 1, 2])
  208. result = i.astype(dtype)
  209. expected = i
  210. tm.assert_index_equal(result, expected)
  211. i = Float64Index([0, 1.1, 2])
  212. result = i.astype(dtype)
  213. expected = Index(i.values.astype(dtype))
  214. tm.assert_index_equal(result, expected)
  215. # invalid
  216. for dtype in ["M8[ns]", "m8[ns]"]:
  217. msg = (
  218. f"Cannot convert Float64Index to dtype {pandas_dtype(dtype)}; "
  219. f"integer values are required for conversion"
  220. )
  221. with pytest.raises(TypeError, match=re.escape(msg)):
  222. i.astype(dtype)
  223. # GH 13149
  224. for dtype in ["int16", "int32", "int64"]:
  225. i = Float64Index([0, 1.1, np.NAN])
  226. msg = r"Cannot convert non-finite values \(NA or inf\) to integer"
  227. with pytest.raises(ValueError, match=msg):
  228. i.astype(dtype)
  229. def test_cannot_cast_inf_to_int(self):
  230. idx = pd.Float64Index([1, 2, np.inf])
  231. msg = r"Cannot convert non-finite values \(NA or inf\) to integer"
  232. with pytest.raises(ValueError, match=msg):
  233. idx.astype(int)
  234. def test_type_coercion_fail(self, any_int_dtype):
  235. # see gh-15832
  236. msg = "Trying to coerce float values to integers"
  237. with pytest.raises(ValueError, match=msg):
  238. Index([1, 2, 3.5], dtype=any_int_dtype)
  239. def test_type_coercion_valid(self, float_dtype):
  240. # There is no Float32Index, so we always
  241. # generate Float64Index.
  242. i = Index([1, 2, 3.5], dtype=float_dtype)
  243. tm.assert_index_equal(i, Index([1, 2, 3.5]))
  244. def test_equals_numeric(self):
  245. i = Float64Index([1.0, 2.0])
  246. assert i.equals(i)
  247. assert i.identical(i)
  248. i2 = Float64Index([1.0, 2.0])
  249. assert i.equals(i2)
  250. i = Float64Index([1.0, np.nan])
  251. assert i.equals(i)
  252. assert i.identical(i)
  253. i2 = Float64Index([1.0, np.nan])
  254. assert i.equals(i2)
  255. def test_get_indexer(self):
  256. idx = Float64Index([0.0, 1.0, 2.0])
  257. tm.assert_numpy_array_equal(
  258. idx.get_indexer(idx), np.array([0, 1, 2], dtype=np.intp)
  259. )
  260. target = [-0.1, 0.5, 1.1]
  261. tm.assert_numpy_array_equal(
  262. idx.get_indexer(target, "pad"), np.array([-1, 0, 1], dtype=np.intp)
  263. )
  264. tm.assert_numpy_array_equal(
  265. idx.get_indexer(target, "backfill"), np.array([0, 1, 2], dtype=np.intp)
  266. )
  267. tm.assert_numpy_array_equal(
  268. idx.get_indexer(target, "nearest"), np.array([0, 1, 1], dtype=np.intp)
  269. )
  270. def test_get_loc(self):
  271. idx = Float64Index([0.0, 1.0, 2.0])
  272. for method in [None, "pad", "backfill", "nearest"]:
  273. assert idx.get_loc(1, method) == 1
  274. if method is not None:
  275. assert idx.get_loc(1, method, tolerance=0) == 1
  276. for method, loc in [("pad", 1), ("backfill", 2), ("nearest", 1)]:
  277. assert idx.get_loc(1.1, method) == loc
  278. assert idx.get_loc(1.1, method, tolerance=0.9) == loc
  279. with pytest.raises(KeyError, match="^'foo'$"):
  280. idx.get_loc("foo")
  281. with pytest.raises(KeyError, match=r"^1\.5$"):
  282. idx.get_loc(1.5)
  283. with pytest.raises(KeyError, match=r"^1\.5$"):
  284. idx.get_loc(1.5, method="pad", tolerance=0.1)
  285. with pytest.raises(KeyError, match="^True$"):
  286. idx.get_loc(True)
  287. with pytest.raises(KeyError, match="^False$"):
  288. idx.get_loc(False)
  289. with pytest.raises(ValueError, match="must be numeric"):
  290. idx.get_loc(1.4, method="nearest", tolerance="foo")
  291. with pytest.raises(ValueError, match="must contain numeric elements"):
  292. idx.get_loc(1.4, method="nearest", tolerance=np.array(["foo"]))
  293. with pytest.raises(
  294. ValueError, match="tolerance size must match target index size"
  295. ):
  296. idx.get_loc(1.4, method="nearest", tolerance=np.array([1, 2]))
  297. def test_get_loc_na(self):
  298. idx = Float64Index([np.nan, 1, 2])
  299. assert idx.get_loc(1) == 1
  300. assert idx.get_loc(np.nan) == 0
  301. idx = Float64Index([np.nan, 1, np.nan])
  302. assert idx.get_loc(1) == 1
  303. # representable by slice [0:2:2]
  304. # pytest.raises(KeyError, idx.slice_locs, np.nan)
  305. sliced = idx.slice_locs(np.nan)
  306. assert isinstance(sliced, tuple)
  307. assert sliced == (0, 3)
  308. # not representable by slice
  309. idx = Float64Index([np.nan, 1, np.nan, np.nan])
  310. assert idx.get_loc(1) == 1
  311. msg = "'Cannot get left slice bound for non-unique label: nan"
  312. with pytest.raises(KeyError, match=msg):
  313. idx.slice_locs(np.nan)
  314. def test_get_loc_missing_nan(self):
  315. # GH 8569
  316. idx = Float64Index([1, 2])
  317. assert idx.get_loc(1) == 0
  318. with pytest.raises(KeyError, match=r"^3\.0$"):
  319. idx.get_loc(3)
  320. with pytest.raises(KeyError, match="^nan$"):
  321. idx.get_loc(np.nan)
  322. with pytest.raises(KeyError, match=r"^\[nan\]$"):
  323. idx.get_loc([np.nan])
  324. def test_contains_nans(self):
  325. i = Float64Index([1.0, 2.0, np.nan])
  326. assert np.nan in i
  327. def test_contains_not_nans(self):
  328. i = Float64Index([1.0, 2.0, np.nan])
  329. assert 1.0 in i
  330. def test_doesnt_contain_all_the_things(self):
  331. i = Float64Index([np.nan])
  332. assert not i.isin([0]).item()
  333. assert not i.isin([1]).item()
  334. assert i.isin([np.nan]).item()
  335. def test_nan_multiple_containment(self):
  336. i = Float64Index([1.0, np.nan])
  337. tm.assert_numpy_array_equal(i.isin([1.0]), np.array([True, False]))
  338. tm.assert_numpy_array_equal(i.isin([2.0, np.pi]), np.array([False, False]))
  339. tm.assert_numpy_array_equal(i.isin([np.nan]), np.array([False, True]))
  340. tm.assert_numpy_array_equal(i.isin([1.0, np.nan]), np.array([True, True]))
  341. i = Float64Index([1.0, 2.0])
  342. tm.assert_numpy_array_equal(i.isin([np.nan]), np.array([False, False]))
  343. def test_astype_from_object(self):
  344. index = Index([1.0, np.nan, 0.2], dtype="object")
  345. result = index.astype(float)
  346. expected = Float64Index([1.0, np.nan, 0.2])
  347. assert result.dtype == expected.dtype
  348. tm.assert_index_equal(result, expected)
  349. def test_fillna_float64(self):
  350. # GH 11343
  351. idx = Index([1.0, np.nan, 3.0], dtype=float, name="x")
  352. # can't downcast
  353. exp = Index([1.0, 0.1, 3.0], name="x")
  354. tm.assert_index_equal(idx.fillna(0.1), exp)
  355. # downcast
  356. exp = Float64Index([1.0, 2.0, 3.0], name="x")
  357. tm.assert_index_equal(idx.fillna(2), exp)
  358. # object
  359. exp = Index([1.0, "obj", 3.0], name="x")
  360. tm.assert_index_equal(idx.fillna("obj"), exp)
  361. def test_take_fill_value(self):
  362. # GH 12631
  363. idx = pd.Float64Index([1.0, 2.0, 3.0], name="xxx")
  364. result = idx.take(np.array([1, 0, -1]))
  365. expected = pd.Float64Index([2.0, 1.0, 3.0], name="xxx")
  366. tm.assert_index_equal(result, expected)
  367. # fill_value
  368. result = idx.take(np.array([1, 0, -1]), fill_value=True)
  369. expected = pd.Float64Index([2.0, 1.0, np.nan], name="xxx")
  370. tm.assert_index_equal(result, expected)
  371. # allow_fill=False
  372. result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True)
  373. expected = pd.Float64Index([2.0, 1.0, 3.0], name="xxx")
  374. tm.assert_index_equal(result, expected)
  375. msg = (
  376. "When allow_fill=True and fill_value is not None, "
  377. "all indices must be >= -1"
  378. )
  379. with pytest.raises(ValueError, match=msg):
  380. idx.take(np.array([1, 0, -2]), fill_value=True)
  381. with pytest.raises(ValueError, match=msg):
  382. idx.take(np.array([1, 0, -5]), fill_value=True)
  383. with pytest.raises(IndexError):
  384. idx.take(np.array([1, -5]))
  385. class NumericInt(Numeric):
  386. def test_view(self):
  387. i = self._holder([], name="Foo")
  388. i_view = i.view()
  389. assert i_view.name == "Foo"
  390. i_view = i.view(self._dtype)
  391. tm.assert_index_equal(i, self._holder(i_view, name="Foo"))
  392. i_view = i.view(self._holder)
  393. tm.assert_index_equal(i, self._holder(i_view, name="Foo"))
  394. def test_is_monotonic(self):
  395. index = self._holder([1, 2, 3, 4])
  396. assert index.is_monotonic is True
  397. assert index.is_monotonic_increasing is True
  398. assert index._is_strictly_monotonic_increasing is True
  399. assert index.is_monotonic_decreasing is False
  400. assert index._is_strictly_monotonic_decreasing is False
  401. index = self._holder([4, 3, 2, 1])
  402. assert index.is_monotonic is False
  403. assert index._is_strictly_monotonic_increasing is False
  404. assert index._is_strictly_monotonic_decreasing is True
  405. index = self._holder([1])
  406. assert index.is_monotonic is True
  407. assert index.is_monotonic_increasing is True
  408. assert index.is_monotonic_decreasing is True
  409. assert index._is_strictly_monotonic_increasing is True
  410. assert index._is_strictly_monotonic_decreasing is True
  411. def test_is_strictly_monotonic(self):
  412. index = self._holder([1, 1, 2, 3])
  413. assert index.is_monotonic_increasing is True
  414. assert index._is_strictly_monotonic_increasing is False
  415. index = self._holder([3, 2, 1, 1])
  416. assert index.is_monotonic_decreasing is True
  417. assert index._is_strictly_monotonic_decreasing is False
  418. index = self._holder([1, 1])
  419. assert index.is_monotonic_increasing
  420. assert index.is_monotonic_decreasing
  421. assert not index._is_strictly_monotonic_increasing
  422. assert not index._is_strictly_monotonic_decreasing
  423. def test_logical_compat(self):
  424. idx = self.create_index()
  425. assert idx.all() == idx.values.all()
  426. assert idx.any() == idx.values.any()
  427. def test_identical(self):
  428. index = self.create_index()
  429. i = Index(index.copy())
  430. assert i.identical(index)
  431. same_values_different_type = Index(i, dtype=object)
  432. assert not i.identical(same_values_different_type)
  433. i = index.copy(dtype=object)
  434. i = i.rename("foo")
  435. same_values = Index(i, dtype=object)
  436. assert same_values.identical(i)
  437. assert not i.identical(index)
  438. assert Index(same_values, name="foo", dtype=object).identical(i)
  439. assert not index.copy(dtype=object).identical(index.copy(dtype=self._dtype))
  440. def test_join_non_unique(self):
  441. left = Index([4, 4, 3, 3])
  442. joined, lidx, ridx = left.join(left, return_indexers=True)
  443. exp_joined = Index([3, 3, 3, 3, 4, 4, 4, 4])
  444. tm.assert_index_equal(joined, exp_joined)
  445. exp_lidx = np.array([2, 2, 3, 3, 0, 0, 1, 1], dtype=np.intp)
  446. tm.assert_numpy_array_equal(lidx, exp_lidx)
  447. exp_ridx = np.array([2, 3, 2, 3, 0, 1, 0, 1], dtype=np.intp)
  448. tm.assert_numpy_array_equal(ridx, exp_ridx)
  449. def test_join_self(self, join_type):
  450. index = self.create_index()
  451. joined = index.join(index, how=join_type)
  452. assert index is joined
  453. def test_union_noncomparable(self):
  454. # corner case, non-Int64Index
  455. index = self.create_index()
  456. other = Index([datetime.now() + timedelta(i) for i in range(4)], dtype=object)
  457. result = index.union(other)
  458. expected = Index(np.concatenate((index, other)))
  459. tm.assert_index_equal(result, expected)
  460. result = other.union(index)
  461. expected = Index(np.concatenate((other, index)))
  462. tm.assert_index_equal(result, expected)
  463. def test_cant_or_shouldnt_cast(self):
  464. msg = (
  465. "String dtype not supported, "
  466. "you may need to explicitly cast to a numeric type"
  467. )
  468. # can't
  469. data = ["foo", "bar", "baz"]
  470. with pytest.raises(TypeError, match=msg):
  471. self._holder(data)
  472. # shouldn't
  473. data = ["0", "1", "2"]
  474. with pytest.raises(TypeError, match=msg):
  475. self._holder(data)
  476. def test_view_index(self):
  477. index = self.create_index()
  478. index.view(Index)
  479. def test_prevent_casting(self):
  480. index = self.create_index()
  481. result = index.astype("O")
  482. assert result.dtype == np.object_
  483. def test_take_preserve_name(self):
  484. index = self._holder([1, 2, 3, 4], name="foo")
  485. taken = index.take([3, 0, 1])
  486. assert index.name == taken.name
  487. def test_take_fill_value(self):
  488. # see gh-12631
  489. idx = self._holder([1, 2, 3], name="xxx")
  490. result = idx.take(np.array([1, 0, -1]))
  491. expected = self._holder([2, 1, 3], name="xxx")
  492. tm.assert_index_equal(result, expected)
  493. name = self._holder.__name__
  494. msg = f"Unable to fill values because {name} cannot contain NA"
  495. # fill_value=True
  496. with pytest.raises(ValueError, match=msg):
  497. idx.take(np.array([1, 0, -1]), fill_value=True)
  498. # allow_fill=False
  499. result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True)
  500. expected = self._holder([2, 1, 3], name="xxx")
  501. tm.assert_index_equal(result, expected)
  502. with pytest.raises(ValueError, match=msg):
  503. idx.take(np.array([1, 0, -2]), fill_value=True)
  504. with pytest.raises(ValueError, match=msg):
  505. idx.take(np.array([1, 0, -5]), fill_value=True)
  506. with pytest.raises(IndexError):
  507. idx.take(np.array([1, -5]))
  508. def test_slice_keep_name(self):
  509. idx = self._holder([1, 2], name="asdf")
  510. assert idx.name == idx[1:].name
  511. class TestInt64Index(NumericInt):
  512. _dtype = "int64"
  513. _holder = Int64Index
  514. @pytest.fixture(
  515. params=[range(0, 20, 2), range(19, -1, -1)], ids=["index_inc", "index_dec"]
  516. )
  517. def indices(self, request):
  518. return Int64Index(request.param)
  519. def create_index(self):
  520. # return Int64Index(np.arange(5, dtype="int64"))
  521. return Int64Index(range(0, 20, 2))
  522. def test_constructor(self):
  523. # pass list, coerce fine
  524. index = Int64Index([-5, 0, 1, 2])
  525. expected = Index([-5, 0, 1, 2], dtype=np.int64)
  526. tm.assert_index_equal(index, expected)
  527. # from iterable
  528. index = Int64Index(iter([-5, 0, 1, 2]))
  529. tm.assert_index_equal(index, expected)
  530. # scalar raise Exception
  531. msg = (
  532. r"Int64Index\(\.\.\.\) must be called with a collection of some "
  533. "kind, 5 was passed"
  534. )
  535. with pytest.raises(TypeError, match=msg):
  536. Int64Index(5)
  537. # copy
  538. arr = index.values
  539. new_index = Int64Index(arr, copy=True)
  540. tm.assert_index_equal(new_index, index)
  541. val = arr[0] + 3000
  542. # this should not change index
  543. arr[0] = val
  544. assert new_index[0] != val
  545. # interpret list-like
  546. expected = Int64Index([5, 0])
  547. for cls in [Index, Int64Index]:
  548. for idx in [
  549. cls([5, 0], dtype="int64"),
  550. cls(np.array([5, 0]), dtype="int64"),
  551. cls(Series([5, 0]), dtype="int64"),
  552. ]:
  553. tm.assert_index_equal(idx, expected)
  554. def test_constructor_corner(self):
  555. arr = np.array([1, 2, 3, 4], dtype=object)
  556. index = Int64Index(arr)
  557. assert index.values.dtype == np.int64
  558. tm.assert_index_equal(index, Index(arr))
  559. # preventing casting
  560. arr = np.array([1, "2", 3, "4"], dtype=object)
  561. with pytest.raises(TypeError, match="casting"):
  562. Int64Index(arr)
  563. arr_with_floats = [0, 2, 3, 4, 5, 1.25, 3, -1]
  564. with pytest.raises(TypeError, match="casting"):
  565. Int64Index(arr_with_floats)
  566. def test_constructor_coercion_signed_to_unsigned(self, uint_dtype):
  567. # see gh-15832
  568. msg = "Trying to coerce negative values to unsigned integers"
  569. with pytest.raises(OverflowError, match=msg):
  570. Index([-1], dtype=uint_dtype)
  571. def test_constructor_unwraps_index(self):
  572. idx = pd.Index([1, 2])
  573. result = pd.Int64Index(idx)
  574. expected = np.array([1, 2], dtype="int64")
  575. tm.assert_numpy_array_equal(result._data, expected)
  576. def test_coerce_list(self):
  577. # coerce things
  578. arr = Index([1, 2, 3, 4])
  579. assert isinstance(arr, Int64Index)
  580. # but not if explicit dtype passed
  581. arr = Index([1, 2, 3, 4], dtype=object)
  582. assert isinstance(arr, Index)
  583. def test_get_indexer(self):
  584. index = self.create_index()
  585. target = Int64Index(np.arange(10))
  586. indexer = index.get_indexer(target)
  587. expected = np.array([0, -1, 1, -1, 2, -1, 3, -1, 4, -1], dtype=np.intp)
  588. tm.assert_numpy_array_equal(indexer, expected)
  589. target = Int64Index(np.arange(10))
  590. indexer = index.get_indexer(target, method="pad")
  591. expected = np.array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4], dtype=np.intp)
  592. tm.assert_numpy_array_equal(indexer, expected)
  593. target = Int64Index(np.arange(10))
  594. indexer = index.get_indexer(target, method="backfill")
  595. expected = np.array([0, 1, 1, 2, 2, 3, 3, 4, 4, 5], dtype=np.intp)
  596. tm.assert_numpy_array_equal(indexer, expected)
  597. def test_get_indexer_nan(self):
  598. # GH 7820
  599. result = Index([1, 2, np.nan]).get_indexer([np.nan])
  600. expected = np.array([2], dtype=np.intp)
  601. tm.assert_numpy_array_equal(result, expected)
  602. def test_intersection(self):
  603. index = self.create_index()
  604. other = Index([1, 2, 3, 4, 5])
  605. result = index.intersection(other)
  606. expected = Index(np.sort(np.intersect1d(index.values, other.values)))
  607. tm.assert_index_equal(result, expected)
  608. result = other.intersection(index)
  609. expected = Index(
  610. np.sort(np.asarray(np.intersect1d(index.values, other.values)))
  611. )
  612. tm.assert_index_equal(result, expected)
  613. def test_join_inner(self):
  614. index = self.create_index()
  615. other = Int64Index([7, 12, 25, 1, 2, 5])
  616. other_mono = Int64Index([1, 2, 5, 7, 12, 25])
  617. # not monotonic
  618. res, lidx, ridx = index.join(other, how="inner", return_indexers=True)
  619. # no guarantee of sortedness, so sort for comparison purposes
  620. ind = res.argsort()
  621. res = res.take(ind)
  622. lidx = lidx.take(ind)
  623. ridx = ridx.take(ind)
  624. eres = Int64Index([2, 12])
  625. elidx = np.array([1, 6], dtype=np.intp)
  626. eridx = np.array([4, 1], dtype=np.intp)
  627. assert isinstance(res, Int64Index)
  628. tm.assert_index_equal(res, eres)
  629. tm.assert_numpy_array_equal(lidx, elidx)
  630. tm.assert_numpy_array_equal(ridx, eridx)
  631. # monotonic
  632. res, lidx, ridx = index.join(other_mono, how="inner", return_indexers=True)
  633. res2 = index.intersection(other_mono)
  634. tm.assert_index_equal(res, res2)
  635. elidx = np.array([1, 6], dtype=np.intp)
  636. eridx = np.array([1, 4], dtype=np.intp)
  637. assert isinstance(res, Int64Index)
  638. tm.assert_index_equal(res, eres)
  639. tm.assert_numpy_array_equal(lidx, elidx)
  640. tm.assert_numpy_array_equal(ridx, eridx)
  641. def test_join_left(self):
  642. index = self.create_index()
  643. other = Int64Index([7, 12, 25, 1, 2, 5])
  644. other_mono = Int64Index([1, 2, 5, 7, 12, 25])
  645. # not monotonic
  646. res, lidx, ridx = index.join(other, how="left", return_indexers=True)
  647. eres = index
  648. eridx = np.array([-1, 4, -1, -1, -1, -1, 1, -1, -1, -1], dtype=np.intp)
  649. assert isinstance(res, Int64Index)
  650. tm.assert_index_equal(res, eres)
  651. assert lidx is None
  652. tm.assert_numpy_array_equal(ridx, eridx)
  653. # monotonic
  654. res, lidx, ridx = index.join(other_mono, how="left", return_indexers=True)
  655. eridx = np.array([-1, 1, -1, -1, -1, -1, 4, -1, -1, -1], dtype=np.intp)
  656. assert isinstance(res, Int64Index)
  657. tm.assert_index_equal(res, eres)
  658. assert lidx is None
  659. tm.assert_numpy_array_equal(ridx, eridx)
  660. # non-unique
  661. idx = Index([1, 1, 2, 5])
  662. idx2 = Index([1, 2, 5, 7, 9])
  663. res, lidx, ridx = idx2.join(idx, how="left", return_indexers=True)
  664. eres = Index([1, 1, 2, 5, 7, 9]) # 1 is in idx2, so it should be x2
  665. eridx = np.array([0, 1, 2, 3, -1, -1], dtype=np.intp)
  666. elidx = np.array([0, 0, 1, 2, 3, 4], dtype=np.intp)
  667. tm.assert_index_equal(res, eres)
  668. tm.assert_numpy_array_equal(lidx, elidx)
  669. tm.assert_numpy_array_equal(ridx, eridx)
  670. def test_join_right(self):
  671. index = self.create_index()
  672. other = Int64Index([7, 12, 25, 1, 2, 5])
  673. other_mono = Int64Index([1, 2, 5, 7, 12, 25])
  674. # not monotonic
  675. res, lidx, ridx = index.join(other, how="right", return_indexers=True)
  676. eres = other
  677. elidx = np.array([-1, 6, -1, -1, 1, -1], dtype=np.intp)
  678. assert isinstance(other, Int64Index)
  679. tm.assert_index_equal(res, eres)
  680. tm.assert_numpy_array_equal(lidx, elidx)
  681. assert ridx is None
  682. # monotonic
  683. res, lidx, ridx = index.join(other_mono, how="right", return_indexers=True)
  684. eres = other_mono
  685. elidx = np.array([-1, 1, -1, -1, 6, -1], dtype=np.intp)
  686. assert isinstance(other, Int64Index)
  687. tm.assert_index_equal(res, eres)
  688. tm.assert_numpy_array_equal(lidx, elidx)
  689. assert ridx is None
  690. # non-unique
  691. idx = Index([1, 1, 2, 5])
  692. idx2 = Index([1, 2, 5, 7, 9])
  693. res, lidx, ridx = idx.join(idx2, how="right", return_indexers=True)
  694. eres = Index([1, 1, 2, 5, 7, 9]) # 1 is in idx2, so it should be x2
  695. elidx = np.array([0, 1, 2, 3, -1, -1], dtype=np.intp)
  696. eridx = np.array([0, 0, 1, 2, 3, 4], dtype=np.intp)
  697. tm.assert_index_equal(res, eres)
  698. tm.assert_numpy_array_equal(lidx, elidx)
  699. tm.assert_numpy_array_equal(ridx, eridx)
  700. def test_join_non_int_index(self):
  701. index = self.create_index()
  702. other = Index([3, 6, 7, 8, 10], dtype=object)
  703. outer = index.join(other, how="outer")
  704. outer2 = other.join(index, how="outer")
  705. expected = Index([0, 2, 3, 4, 6, 7, 8, 10, 12, 14, 16, 18])
  706. tm.assert_index_equal(outer, outer2)
  707. tm.assert_index_equal(outer, expected)
  708. inner = index.join(other, how="inner")
  709. inner2 = other.join(index, how="inner")
  710. expected = Index([6, 8, 10])
  711. tm.assert_index_equal(inner, inner2)
  712. tm.assert_index_equal(inner, expected)
  713. left = index.join(other, how="left")
  714. tm.assert_index_equal(left, index.astype(object))
  715. left2 = other.join(index, how="left")
  716. tm.assert_index_equal(left2, other)
  717. right = index.join(other, how="right")
  718. tm.assert_index_equal(right, other)
  719. right2 = other.join(index, how="right")
  720. tm.assert_index_equal(right2, index.astype(object))
  721. def test_join_outer(self):
  722. index = self.create_index()
  723. other = Int64Index([7, 12, 25, 1, 2, 5])
  724. other_mono = Int64Index([1, 2, 5, 7, 12, 25])
  725. # not monotonic
  726. # guarantee of sortedness
  727. res, lidx, ridx = index.join(other, how="outer", return_indexers=True)
  728. noidx_res = index.join(other, how="outer")
  729. tm.assert_index_equal(res, noidx_res)
  730. eres = Int64Index([0, 1, 2, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 25])
  731. elidx = np.array([0, -1, 1, 2, -1, 3, -1, 4, 5, 6, 7, 8, 9, -1], dtype=np.intp)
  732. eridx = np.array(
  733. [-1, 3, 4, -1, 5, -1, 0, -1, -1, 1, -1, -1, -1, 2], dtype=np.intp
  734. )
  735. assert isinstance(res, Int64Index)
  736. tm.assert_index_equal(res, eres)
  737. tm.assert_numpy_array_equal(lidx, elidx)
  738. tm.assert_numpy_array_equal(ridx, eridx)
  739. # monotonic
  740. res, lidx, ridx = index.join(other_mono, how="outer", return_indexers=True)
  741. noidx_res = index.join(other_mono, how="outer")
  742. tm.assert_index_equal(res, noidx_res)
  743. elidx = np.array([0, -1, 1, 2, -1, 3, -1, 4, 5, 6, 7, 8, 9, -1], dtype=np.intp)
  744. eridx = np.array(
  745. [-1, 0, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, -1, 5], dtype=np.intp
  746. )
  747. assert isinstance(res, Int64Index)
  748. tm.assert_index_equal(res, eres)
  749. tm.assert_numpy_array_equal(lidx, elidx)
  750. tm.assert_numpy_array_equal(ridx, eridx)
  751. class TestUInt64Index(NumericInt):
  752. _dtype = "uint64"
  753. _holder = UInt64Index
  754. @pytest.fixture(
  755. params=[
  756. [2 ** 63, 2 ** 63 + 10, 2 ** 63 + 15, 2 ** 63 + 20, 2 ** 63 + 25],
  757. [2 ** 63 + 25, 2 ** 63 + 20, 2 ** 63 + 15, 2 ** 63 + 10, 2 ** 63],
  758. ],
  759. ids=["index_inc", "index_dec"],
  760. )
  761. def indices(self, request):
  762. return UInt64Index(request.param)
  763. @pytest.fixture
  764. def index_large(self):
  765. # large values used in TestUInt64Index where no compat needed with Int64/Float64
  766. large = [2 ** 63, 2 ** 63 + 10, 2 ** 63 + 15, 2 ** 63 + 20, 2 ** 63 + 25]
  767. return UInt64Index(large)
  768. def create_index(self):
  769. # compat with shared Int64/Float64 tests; use index_large for UInt64 only tests
  770. return UInt64Index(np.arange(5, dtype="uint64"))
  771. def test_constructor(self):
  772. idx = UInt64Index([1, 2, 3])
  773. res = Index([1, 2, 3], dtype=np.uint64)
  774. tm.assert_index_equal(res, idx)
  775. idx = UInt64Index([1, 2 ** 63])
  776. res = Index([1, 2 ** 63], dtype=np.uint64)
  777. tm.assert_index_equal(res, idx)
  778. idx = UInt64Index([1, 2 ** 63])
  779. res = Index([1, 2 ** 63])
  780. tm.assert_index_equal(res, idx)
  781. idx = Index([-1, 2 ** 63], dtype=object)
  782. res = Index(np.array([-1, 2 ** 63], dtype=object))
  783. tm.assert_index_equal(res, idx)
  784. # https://github.com/pandas-dev/pandas/issues/29526
  785. idx = UInt64Index([1, 2 ** 63 + 1], dtype=np.uint64)
  786. res = Index([1, 2 ** 63 + 1], dtype=np.uint64)
  787. tm.assert_index_equal(res, idx)
  788. def test_get_indexer(self, index_large):
  789. target = UInt64Index(np.arange(10).astype("uint64") * 5 + 2 ** 63)
  790. indexer = index_large.get_indexer(target)
  791. expected = np.array([0, -1, 1, 2, 3, 4, -1, -1, -1, -1], dtype=np.intp)
  792. tm.assert_numpy_array_equal(indexer, expected)
  793. target = UInt64Index(np.arange(10).astype("uint64") * 5 + 2 ** 63)
  794. indexer = index_large.get_indexer(target, method="pad")
  795. expected = np.array([0, 0, 1, 2, 3, 4, 4, 4, 4, 4], dtype=np.intp)
  796. tm.assert_numpy_array_equal(indexer, expected)
  797. target = UInt64Index(np.arange(10).astype("uint64") * 5 + 2 ** 63)
  798. indexer = index_large.get_indexer(target, method="backfill")
  799. expected = np.array([0, 1, 1, 2, 3, 4, -1, -1, -1, -1], dtype=np.intp)
  800. tm.assert_numpy_array_equal(indexer, expected)
  801. def test_intersection(self, index_large):
  802. other = Index([2 ** 63, 2 ** 63 + 5, 2 ** 63 + 10, 2 ** 63 + 15, 2 ** 63 + 20])
  803. result = index_large.intersection(other)
  804. expected = Index(np.sort(np.intersect1d(index_large.values, other.values)))
  805. tm.assert_index_equal(result, expected)
  806. result = other.intersection(index_large)
  807. expected = Index(
  808. np.sort(np.asarray(np.intersect1d(index_large.values, other.values)))
  809. )
  810. tm.assert_index_equal(result, expected)
  811. def test_join_inner(self, index_large):
  812. other = UInt64Index(2 ** 63 + np.array([7, 12, 25, 1, 2, 10], dtype="uint64"))
  813. other_mono = UInt64Index(
  814. 2 ** 63 + np.array([1, 2, 7, 10, 12, 25], dtype="uint64")
  815. )
  816. # not monotonic
  817. res, lidx, ridx = index_large.join(other, how="inner", return_indexers=True)
  818. # no guarantee of sortedness, so sort for comparison purposes
  819. ind = res.argsort()
  820. res = res.take(ind)
  821. lidx = lidx.take(ind)
  822. ridx = ridx.take(ind)
  823. eres = UInt64Index(2 ** 63 + np.array([10, 25], dtype="uint64"))
  824. elidx = np.array([1, 4], dtype=np.intp)
  825. eridx = np.array([5, 2], dtype=np.intp)
  826. assert isinstance(res, UInt64Index)
  827. tm.assert_index_equal(res, eres)
  828. tm.assert_numpy_array_equal(lidx, elidx)
  829. tm.assert_numpy_array_equal(ridx, eridx)
  830. # monotonic
  831. res, lidx, ridx = index_large.join(
  832. other_mono, how="inner", return_indexers=True
  833. )
  834. res2 = index_large.intersection(other_mono)
  835. tm.assert_index_equal(res, res2)
  836. elidx = np.array([1, 4], dtype=np.intp)
  837. eridx = np.array([3, 5], dtype=np.intp)
  838. assert isinstance(res, UInt64Index)
  839. tm.assert_index_equal(res, eres)
  840. tm.assert_numpy_array_equal(lidx, elidx)
  841. tm.assert_numpy_array_equal(ridx, eridx)
  842. def test_join_left(self, index_large):
  843. other = UInt64Index(2 ** 63 + np.array([7, 12, 25, 1, 2, 10], dtype="uint64"))
  844. other_mono = UInt64Index(
  845. 2 ** 63 + np.array([1, 2, 7, 10, 12, 25], dtype="uint64")
  846. )
  847. # not monotonic
  848. res, lidx, ridx = index_large.join(other, how="left", return_indexers=True)
  849. eres = index_large
  850. eridx = np.array([-1, 5, -1, -1, 2], dtype=np.intp)
  851. assert isinstance(res, UInt64Index)
  852. tm.assert_index_equal(res, eres)
  853. assert lidx is None
  854. tm.assert_numpy_array_equal(ridx, eridx)
  855. # monotonic
  856. res, lidx, ridx = index_large.join(other_mono, how="left", return_indexers=True)
  857. eridx = np.array([-1, 3, -1, -1, 5], dtype=np.intp)
  858. assert isinstance(res, UInt64Index)
  859. tm.assert_index_equal(res, eres)
  860. assert lidx is None
  861. tm.assert_numpy_array_equal(ridx, eridx)
  862. # non-unique
  863. idx = UInt64Index(2 ** 63 + np.array([1, 1, 2, 5], dtype="uint64"))
  864. idx2 = UInt64Index(2 ** 63 + np.array([1, 2, 5, 7, 9], dtype="uint64"))
  865. res, lidx, ridx = idx2.join(idx, how="left", return_indexers=True)
  866. # 1 is in idx2, so it should be x2
  867. eres = UInt64Index(2 ** 63 + np.array([1, 1, 2, 5, 7, 9], dtype="uint64"))
  868. eridx = np.array([0, 1, 2, 3, -1, -1], dtype=np.intp)
  869. elidx = np.array([0, 0, 1, 2, 3, 4], dtype=np.intp)
  870. tm.assert_index_equal(res, eres)
  871. tm.assert_numpy_array_equal(lidx, elidx)
  872. tm.assert_numpy_array_equal(ridx, eridx)
  873. def test_join_right(self, index_large):
  874. other = UInt64Index(2 ** 63 + np.array([7, 12, 25, 1, 2, 10], dtype="uint64"))
  875. other_mono = UInt64Index(
  876. 2 ** 63 + np.array([1, 2, 7, 10, 12, 25], dtype="uint64")
  877. )
  878. # not monotonic
  879. res, lidx, ridx = index_large.join(other, how="right", return_indexers=True)
  880. eres = other
  881. elidx = np.array([-1, -1, 4, -1, -1, 1], dtype=np.intp)
  882. tm.assert_numpy_array_equal(lidx, elidx)
  883. assert isinstance(other, UInt64Index)
  884. tm.assert_index_equal(res, eres)
  885. assert ridx is None
  886. # monotonic
  887. res, lidx, ridx = index_large.join(
  888. other_mono, how="right", return_indexers=True
  889. )
  890. eres = other_mono
  891. elidx = np.array([-1, -1, -1, 1, -1, 4], dtype=np.intp)
  892. assert isinstance(other, UInt64Index)
  893. tm.assert_numpy_array_equal(lidx, elidx)
  894. tm.assert_index_equal(res, eres)
  895. assert ridx is None
  896. # non-unique
  897. idx = UInt64Index(2 ** 63 + np.array([1, 1, 2, 5], dtype="uint64"))
  898. idx2 = UInt64Index(2 ** 63 + np.array([1, 2, 5, 7, 9], dtype="uint64"))
  899. res, lidx, ridx = idx.join(idx2, how="right", return_indexers=True)
  900. # 1 is in idx2, so it should be x2
  901. eres = UInt64Index(2 ** 63 + np.array([1, 1, 2, 5, 7, 9], dtype="uint64"))
  902. elidx = np.array([0, 1, 2, 3, -1, -1], dtype=np.intp)
  903. eridx = np.array([0, 0, 1, 2, 3, 4], dtype=np.intp)
  904. tm.assert_index_equal(res, eres)
  905. tm.assert_numpy_array_equal(lidx, elidx)
  906. tm.assert_numpy_array_equal(ridx, eridx)
  907. def test_join_non_int_index(self, index_large):
  908. other = Index(
  909. 2 ** 63 + np.array([1, 5, 7, 10, 20], dtype="uint64"), dtype=object
  910. )
  911. outer = index_large.join(other, how="outer")
  912. outer2 = other.join(index_large, how="outer")
  913. expected = Index(
  914. 2 ** 63 + np.array([0, 1, 5, 7, 10, 15, 20, 25], dtype="uint64")
  915. )
  916. tm.assert_index_equal(outer, outer2)
  917. tm.assert_index_equal(outer, expected)
  918. inner = index_large.join(other, how="inner")
  919. inner2 = other.join(index_large, how="inner")
  920. expected = Index(2 ** 63 + np.array([10, 20], dtype="uint64"))
  921. tm.assert_index_equal(inner, inner2)
  922. tm.assert_index_equal(inner, expected)
  923. left = index_large.join(other, how="left")
  924. tm.assert_index_equal(left, index_large.astype(object))
  925. left2 = other.join(index_large, how="left")
  926. tm.assert_index_equal(left2, other)
  927. right = index_large.join(other, how="right")
  928. tm.assert_index_equal(right, other)
  929. right2 = other.join(index_large, how="right")
  930. tm.assert_index_equal(right2, index_large.astype(object))
  931. def test_join_outer(self, index_large):
  932. other = UInt64Index(2 ** 63 + np.array([7, 12, 25, 1, 2, 10], dtype="uint64"))
  933. other_mono = UInt64Index(
  934. 2 ** 63 + np.array([1, 2, 7, 10, 12, 25], dtype="uint64")
  935. )
  936. # not monotonic
  937. # guarantee of sortedness
  938. res, lidx, ridx = index_large.join(other, how="outer", return_indexers=True)
  939. noidx_res = index_large.join(other, how="outer")
  940. tm.assert_index_equal(res, noidx_res)
  941. eres = UInt64Index(
  942. 2 ** 63 + np.array([0, 1, 2, 7, 10, 12, 15, 20, 25], dtype="uint64")
  943. )
  944. elidx = np.array([0, -1, -1, -1, 1, -1, 2, 3, 4], dtype=np.intp)
  945. eridx = np.array([-1, 3, 4, 0, 5, 1, -1, -1, 2], dtype=np.intp)
  946. assert isinstance(res, UInt64Index)
  947. tm.assert_index_equal(res, eres)
  948. tm.assert_numpy_array_equal(lidx, elidx)
  949. tm.assert_numpy_array_equal(ridx, eridx)
  950. # monotonic
  951. res, lidx, ridx = index_large.join(
  952. other_mono, how="outer", return_indexers=True
  953. )
  954. noidx_res = index_large.join(other_mono, how="outer")
  955. tm.assert_index_equal(res, noidx_res)
  956. elidx = np.array([0, -1, -1, -1, 1, -1, 2, 3, 4], dtype=np.intp)
  957. eridx = np.array([-1, 0, 1, 2, 3, 4, -1, -1, 5], dtype=np.intp)
  958. assert isinstance(res, UInt64Index)
  959. tm.assert_index_equal(res, eres)
  960. tm.assert_numpy_array_equal(lidx, elidx)
  961. tm.assert_numpy_array_equal(ridx, eridx)
  962. @pytest.mark.parametrize("dtype", ["int64", "uint64"])
  963. def test_int_float_union_dtype(dtype):
  964. # https://github.com/pandas-dev/pandas/issues/26778
  965. # [u]int | float -> float
  966. index = pd.Index([0, 2, 3], dtype=dtype)
  967. other = pd.Float64Index([0.5, 1.5])
  968. expected = pd.Float64Index([0.0, 0.5, 1.5, 2.0, 3.0])
  969. result = index.union(other)
  970. tm.assert_index_equal(result, expected)
  971. result = other.union(index)
  972. tm.assert_index_equal(result, expected)
  973. def test_range_float_union_dtype():
  974. # https://github.com/pandas-dev/pandas/issues/26778
  975. index = pd.RangeIndex(start=0, stop=3)
  976. other = pd.Float64Index([0.5, 1.5])
  977. result = index.union(other)
  978. expected = pd.Float64Index([0.0, 0.5, 1, 1.5, 2.0])
  979. tm.assert_index_equal(result, expected)
  980. result = other.union(index)
  981. tm.assert_index_equal(result, expected)
  982. def test_uint_index_does_not_convert_to_float64():
  983. # https://github.com/pandas-dev/pandas/issues/28279
  984. # https://github.com/pandas-dev/pandas/issues/28023
  985. series = pd.Series(
  986. [0, 1, 2, 3, 4, 5],
  987. index=[
  988. 7606741985629028552,
  989. 17876870360202815256,
  990. 17876870360202815256,
  991. 13106359306506049338,
  992. 8991270399732411471,
  993. 8991270399732411472,
  994. ],
  995. )
  996. result = series.loc[[7606741985629028552, 17876870360202815256]]
  997. expected = UInt64Index(
  998. [7606741985629028552, 17876870360202815256, 17876870360202815256],
  999. dtype="uint64",
  1000. )
  1001. tm.assert_index_equal(result.index, expected)
  1002. tm.assert_equal(result, series[:3])