test_analytics.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import numpy as np
  2. import pytest
  3. import pandas as pd
  4. from pandas import (
  5. Index,
  6. MultiIndex,
  7. date_range,
  8. period_range,
  9. )
  10. import pandas._testing as tm
  11. def test_infer_objects(idx):
  12. with pytest.raises(NotImplementedError, match="to_frame"):
  13. idx.infer_objects()
  14. def test_shift(idx):
  15. # GH8083 test the base class for shift
  16. msg = (
  17. "This method is only implemented for DatetimeIndex, PeriodIndex and "
  18. "TimedeltaIndex; Got type MultiIndex"
  19. )
  20. with pytest.raises(NotImplementedError, match=msg):
  21. idx.shift(1)
  22. with pytest.raises(NotImplementedError, match=msg):
  23. idx.shift(1, 2)
  24. def test_groupby(idx):
  25. groups = idx.groupby(np.array([1, 1, 1, 2, 2, 2]))
  26. labels = idx.tolist()
  27. exp = {1: labels[:3], 2: labels[3:]}
  28. tm.assert_dict_equal(groups, exp)
  29. # GH5620
  30. groups = idx.groupby(idx)
  31. exp = {key: [key] for key in idx}
  32. tm.assert_dict_equal(groups, exp)
  33. def test_truncate_multiindex():
  34. # GH 34564 for MultiIndex level names check
  35. major_axis = Index(list(range(4)))
  36. minor_axis = Index(list(range(2)))
  37. major_codes = np.array([0, 0, 1, 2, 3, 3])
  38. minor_codes = np.array([0, 1, 0, 1, 0, 1])
  39. index = MultiIndex(
  40. levels=[major_axis, minor_axis],
  41. codes=[major_codes, minor_codes],
  42. names=["L1", "L2"],
  43. )
  44. result = index.truncate(before=1)
  45. assert "foo" not in result.levels[0]
  46. assert 1 in result.levels[0]
  47. assert index.names == result.names
  48. result = index.truncate(after=1)
  49. assert 2 not in result.levels[0]
  50. assert 1 in result.levels[0]
  51. assert index.names == result.names
  52. result = index.truncate(before=1, after=2)
  53. assert len(result.levels[0]) == 2
  54. assert index.names == result.names
  55. msg = "after < before"
  56. with pytest.raises(ValueError, match=msg):
  57. index.truncate(3, 1)
  58. # TODO: reshape
  59. def test_reorder_levels(idx):
  60. # this blows up
  61. with pytest.raises(IndexError, match="^Too many levels"):
  62. idx.reorder_levels([2, 1, 0])
  63. def test_numpy_repeat():
  64. reps = 2
  65. numbers = [1, 2, 3]
  66. names = np.array(["foo", "bar"])
  67. m = MultiIndex.from_product([numbers, names], names=names)
  68. expected = MultiIndex.from_product([numbers, names.repeat(reps)], names=names)
  69. tm.assert_index_equal(np.repeat(m, reps), expected)
  70. msg = "the 'axis' parameter is not supported"
  71. with pytest.raises(ValueError, match=msg):
  72. np.repeat(m, reps, axis=1)
  73. def test_append_mixed_dtypes():
  74. # GH 13660
  75. dti = date_range("2011-01-01", freq="M", periods=3)
  76. dti_tz = date_range("2011-01-01", freq="M", periods=3, tz="US/Eastern")
  77. pi = period_range("2011-01", freq="M", periods=3)
  78. mi = MultiIndex.from_arrays(
  79. [[1, 2, 3], [1.1, np.nan, 3.3], ["a", "b", "c"], dti, dti_tz, pi]
  80. )
  81. assert mi.nlevels == 6
  82. res = mi.append(mi)
  83. exp = MultiIndex.from_arrays(
  84. [
  85. [1, 2, 3, 1, 2, 3],
  86. [1.1, np.nan, 3.3, 1.1, np.nan, 3.3],
  87. ["a", "b", "c", "a", "b", "c"],
  88. dti.append(dti),
  89. dti_tz.append(dti_tz),
  90. pi.append(pi),
  91. ]
  92. )
  93. tm.assert_index_equal(res, exp)
  94. other = MultiIndex.from_arrays(
  95. [
  96. ["x", "y", "z"],
  97. ["x", "y", "z"],
  98. ["x", "y", "z"],
  99. ["x", "y", "z"],
  100. ["x", "y", "z"],
  101. ["x", "y", "z"],
  102. ]
  103. )
  104. res = mi.append(other)
  105. exp = MultiIndex.from_arrays(
  106. [
  107. [1, 2, 3, "x", "y", "z"],
  108. [1.1, np.nan, 3.3, "x", "y", "z"],
  109. ["a", "b", "c", "x", "y", "z"],
  110. dti.append(Index(["x", "y", "z"])),
  111. dti_tz.append(Index(["x", "y", "z"])),
  112. pi.append(Index(["x", "y", "z"])),
  113. ]
  114. )
  115. tm.assert_index_equal(res, exp)
  116. def test_iter(idx):
  117. result = list(idx)
  118. expected = [
  119. ("foo", "one"),
  120. ("foo", "two"),
  121. ("bar", "one"),
  122. ("baz", "two"),
  123. ("qux", "one"),
  124. ("qux", "two"),
  125. ]
  126. assert result == expected
  127. def test_sub(idx):
  128. first = idx
  129. # - now raises (previously was set op difference)
  130. msg = "cannot perform __sub__ with this index type: MultiIndex"
  131. with pytest.raises(TypeError, match=msg):
  132. first - idx[-3:]
  133. with pytest.raises(TypeError, match=msg):
  134. idx[-3:] - first
  135. with pytest.raises(TypeError, match=msg):
  136. idx[-3:] - first.tolist()
  137. msg = "cannot perform __rsub__ with this index type: MultiIndex"
  138. with pytest.raises(TypeError, match=msg):
  139. first.tolist() - idx[-3:]
  140. def test_map(idx):
  141. # callable
  142. index = idx
  143. result = index.map(lambda x: x)
  144. tm.assert_index_equal(result, index)
  145. @pytest.mark.parametrize(
  146. "mapper",
  147. [
  148. lambda values, idx: {i: e for e, i in zip(values, idx)},
  149. lambda values, idx: pd.Series(values, idx),
  150. ],
  151. )
  152. def test_map_dictlike(idx, mapper):
  153. identity = mapper(idx.values, idx)
  154. # we don't infer to uint64 dtype for a dict
  155. if idx.dtype == np.uint64 and isinstance(identity, dict):
  156. expected = idx.astype("int64")
  157. else:
  158. expected = idx
  159. result = idx.map(identity)
  160. tm.assert_index_equal(result, expected)
  161. # empty mappable
  162. expected = Index([np.nan] * len(idx))
  163. result = idx.map(mapper(expected, idx))
  164. tm.assert_index_equal(result, expected)
  165. @pytest.mark.parametrize(
  166. "func",
  167. [
  168. np.exp,
  169. np.exp2,
  170. np.expm1,
  171. np.log,
  172. np.log2,
  173. np.log10,
  174. np.log1p,
  175. np.sqrt,
  176. np.sin,
  177. np.cos,
  178. np.tan,
  179. np.arcsin,
  180. np.arccos,
  181. np.arctan,
  182. np.sinh,
  183. np.cosh,
  184. np.tanh,
  185. np.arcsinh,
  186. np.arccosh,
  187. np.arctanh,
  188. np.deg2rad,
  189. np.rad2deg,
  190. ],
  191. ids=lambda func: func.__name__,
  192. )
  193. def test_numpy_ufuncs(idx, func):
  194. # test ufuncs of numpy. see:
  195. # https://numpy.org/doc/stable/reference/ufuncs.html
  196. expected_exception = TypeError
  197. msg = (
  198. "loop of ufunc does not support argument 0 of type tuple which "
  199. f"has no callable {func.__name__} method"
  200. )
  201. with pytest.raises(expected_exception, match=msg):
  202. func(idx)
  203. @pytest.mark.parametrize(
  204. "func",
  205. [np.isfinite, np.isinf, np.isnan, np.signbit],
  206. ids=lambda func: func.__name__,
  207. )
  208. def test_numpy_type_funcs(idx, func):
  209. msg = (
  210. f"ufunc '{func.__name__}' not supported for the input types, and the inputs "
  211. "could not be safely coerced to any supported types according to "
  212. "the casting rule ''safe''"
  213. )
  214. with pytest.raises(TypeError, match=msg):
  215. func(idx)