test_analytics.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import pytest
  4. from pandas.compat import lrange
  5. from pandas.compat.numpy import _np_version_under1p17
  6. import pandas as pd
  7. from pandas import Index, MultiIndex, date_range, period_range
  8. import pandas.util.testing as tm
  9. def test_shift(idx):
  10. # GH8083 test the base class for shift
  11. pytest.raises(NotImplementedError, idx.shift, 1)
  12. pytest.raises(NotImplementedError, idx.shift, 1, 2)
  13. def test_groupby(idx):
  14. groups = idx.groupby(np.array([1, 1, 1, 2, 2, 2]))
  15. labels = idx.get_values().tolist()
  16. exp = {1: labels[:3], 2: labels[3:]}
  17. tm.assert_dict_equal(groups, exp)
  18. # GH5620
  19. groups = idx.groupby(idx)
  20. exp = {key: [key] for key in idx}
  21. tm.assert_dict_equal(groups, exp)
  22. def test_truncate():
  23. major_axis = Index(lrange(4))
  24. minor_axis = Index(lrange(2))
  25. major_codes = np.array([0, 0, 1, 2, 3, 3])
  26. minor_codes = np.array([0, 1, 0, 1, 0, 1])
  27. index = MultiIndex(levels=[major_axis, minor_axis],
  28. codes=[major_codes, minor_codes])
  29. result = index.truncate(before=1)
  30. assert 'foo' not in result.levels[0]
  31. assert 1 in result.levels[0]
  32. result = index.truncate(after=1)
  33. assert 2 not in result.levels[0]
  34. assert 1 in result.levels[0]
  35. result = index.truncate(before=1, after=2)
  36. assert len(result.levels[0]) == 2
  37. # after < before
  38. pytest.raises(ValueError, index.truncate, 3, 1)
  39. def test_where():
  40. i = MultiIndex.from_tuples([('A', 1), ('A', 2)])
  41. with pytest.raises(NotImplementedError):
  42. i.where(True)
  43. def test_where_array_like():
  44. i = MultiIndex.from_tuples([('A', 1), ('A', 2)])
  45. klasses = [list, tuple, np.array, pd.Series]
  46. cond = [False, True]
  47. for klass in klasses:
  48. with pytest.raises(NotImplementedError):
  49. i.where(klass(cond))
  50. # TODO: reshape
  51. def test_reorder_levels(idx):
  52. # this blows up
  53. with pytest.raises(IndexError, match='^Too many levels'):
  54. idx.reorder_levels([2, 1, 0])
  55. def test_numpy_repeat():
  56. reps = 2
  57. numbers = [1, 2, 3]
  58. names = np.array(['foo', 'bar'])
  59. m = MultiIndex.from_product([
  60. numbers, names], names=names)
  61. expected = MultiIndex.from_product([
  62. numbers, names.repeat(reps)], names=names)
  63. tm.assert_index_equal(np.repeat(m, reps), expected)
  64. msg = "the 'axis' parameter is not supported"
  65. with pytest.raises(ValueError, match=msg):
  66. np.repeat(m, reps, axis=1)
  67. def test_append_mixed_dtypes():
  68. # GH 13660
  69. dti = date_range('2011-01-01', freq='M', periods=3, )
  70. dti_tz = date_range('2011-01-01', freq='M', periods=3, tz='US/Eastern')
  71. pi = period_range('2011-01', freq='M', periods=3)
  72. mi = MultiIndex.from_arrays([[1, 2, 3],
  73. [1.1, np.nan, 3.3],
  74. ['a', 'b', 'c'],
  75. dti, dti_tz, pi])
  76. assert mi.nlevels == 6
  77. res = mi.append(mi)
  78. exp = MultiIndex.from_arrays([[1, 2, 3, 1, 2, 3],
  79. [1.1, np.nan, 3.3, 1.1, np.nan, 3.3],
  80. ['a', 'b', 'c', 'a', 'b', 'c'],
  81. dti.append(dti),
  82. dti_tz.append(dti_tz),
  83. pi.append(pi)])
  84. tm.assert_index_equal(res, exp)
  85. other = MultiIndex.from_arrays([['x', 'y', 'z'], ['x', 'y', 'z'],
  86. ['x', 'y', 'z'], ['x', 'y', 'z'],
  87. ['x', 'y', 'z'], ['x', 'y', 'z']])
  88. res = mi.append(other)
  89. exp = MultiIndex.from_arrays([[1, 2, 3, 'x', 'y', 'z'],
  90. [1.1, np.nan, 3.3, 'x', 'y', 'z'],
  91. ['a', 'b', 'c', 'x', 'y', 'z'],
  92. dti.append(pd.Index(['x', 'y', 'z'])),
  93. dti_tz.append(pd.Index(['x', 'y', 'z'])),
  94. pi.append(pd.Index(['x', 'y', 'z']))])
  95. tm.assert_index_equal(res, exp)
  96. def test_take(idx):
  97. indexer = [4, 3, 0, 2]
  98. result = idx.take(indexer)
  99. expected = idx[indexer]
  100. assert result.equals(expected)
  101. # TODO: Remove Commented Code
  102. # if not isinstance(idx,
  103. # (DatetimeIndex, PeriodIndex, TimedeltaIndex)):
  104. # GH 10791
  105. with pytest.raises(AttributeError):
  106. idx.freq
  107. def test_take_invalid_kwargs(idx):
  108. idx = idx
  109. indices = [1, 2]
  110. msg = r"take\(\) got an unexpected keyword argument 'foo'"
  111. with pytest.raises(TypeError, match=msg):
  112. idx.take(indices, foo=2)
  113. msg = "the 'out' parameter is not supported"
  114. with pytest.raises(ValueError, match=msg):
  115. idx.take(indices, out=indices)
  116. msg = "the 'mode' parameter is not supported"
  117. with pytest.raises(ValueError, match=msg):
  118. idx.take(indices, mode='clip')
  119. def test_take_fill_value():
  120. # GH 12631
  121. vals = [['A', 'B'],
  122. [pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02')]]
  123. idx = pd.MultiIndex.from_product(vals, names=['str', 'dt'])
  124. result = idx.take(np.array([1, 0, -1]))
  125. exp_vals = [('A', pd.Timestamp('2011-01-02')),
  126. ('A', pd.Timestamp('2011-01-01')),
  127. ('B', pd.Timestamp('2011-01-02'))]
  128. expected = pd.MultiIndex.from_tuples(exp_vals, names=['str', 'dt'])
  129. tm.assert_index_equal(result, expected)
  130. # fill_value
  131. result = idx.take(np.array([1, 0, -1]), fill_value=True)
  132. exp_vals = [('A', pd.Timestamp('2011-01-02')),
  133. ('A', pd.Timestamp('2011-01-01')),
  134. (np.nan, pd.NaT)]
  135. expected = pd.MultiIndex.from_tuples(exp_vals, names=['str', 'dt'])
  136. tm.assert_index_equal(result, expected)
  137. # allow_fill=False
  138. result = idx.take(np.array([1, 0, -1]), allow_fill=False,
  139. fill_value=True)
  140. exp_vals = [('A', pd.Timestamp('2011-01-02')),
  141. ('A', pd.Timestamp('2011-01-01')),
  142. ('B', pd.Timestamp('2011-01-02'))]
  143. expected = pd.MultiIndex.from_tuples(exp_vals, names=['str', 'dt'])
  144. tm.assert_index_equal(result, expected)
  145. msg = ('When allow_fill=True and fill_value is not None, '
  146. 'all indices must be >= -1')
  147. with pytest.raises(ValueError, match=msg):
  148. idx.take(np.array([1, 0, -2]), fill_value=True)
  149. with pytest.raises(ValueError, match=msg):
  150. idx.take(np.array([1, 0, -5]), fill_value=True)
  151. with pytest.raises(IndexError):
  152. idx.take(np.array([1, -5]))
  153. def test_iter(idx):
  154. result = list(idx)
  155. expected = [('foo', 'one'), ('foo', 'two'), ('bar', 'one'),
  156. ('baz', 'two'), ('qux', 'one'), ('qux', 'two')]
  157. assert result == expected
  158. def test_sub(idx):
  159. first = idx
  160. # - now raises (previously was set op difference)
  161. with pytest.raises(TypeError):
  162. first - idx[-3:]
  163. with pytest.raises(TypeError):
  164. idx[-3:] - first
  165. with pytest.raises(TypeError):
  166. idx[-3:] - first.tolist()
  167. with pytest.raises(TypeError):
  168. first.tolist() - idx[-3:]
  169. def test_map(idx):
  170. # callable
  171. index = idx
  172. # we don't infer UInt64
  173. if isinstance(index, pd.UInt64Index):
  174. expected = index.astype('int64')
  175. else:
  176. expected = index
  177. result = index.map(lambda x: x)
  178. tm.assert_index_equal(result, expected)
  179. @pytest.mark.parametrize(
  180. "mapper",
  181. [
  182. lambda values, idx: {i: e for e, i in zip(values, idx)},
  183. lambda values, idx: pd.Series(values, idx)])
  184. def test_map_dictlike(idx, mapper):
  185. if isinstance(idx, (pd.CategoricalIndex, pd.IntervalIndex)):
  186. pytest.skip("skipping tests for {}".format(type(idx)))
  187. identity = mapper(idx.values, idx)
  188. # we don't infer to UInt64 for a dict
  189. if isinstance(idx, pd.UInt64Index) and isinstance(identity, dict):
  190. expected = idx.astype('int64')
  191. else:
  192. expected = idx
  193. result = idx.map(identity)
  194. tm.assert_index_equal(result, expected)
  195. # empty mappable
  196. expected = pd.Index([np.nan] * len(idx))
  197. result = idx.map(mapper(expected, idx))
  198. tm.assert_index_equal(result, expected)
  199. @pytest.mark.parametrize('func', [
  200. np.exp, np.exp2, np.expm1, np.log, np.log2, np.log10,
  201. np.log1p, np.sqrt, np.sin, np.cos, np.tan, np.arcsin,
  202. np.arccos, np.arctan, np.sinh, np.cosh, np.tanh,
  203. np.arcsinh, np.arccosh, np.arctanh, np.deg2rad,
  204. np.rad2deg
  205. ])
  206. def test_numpy_ufuncs(func):
  207. # test ufuncs of numpy. see:
  208. # http://docs.scipy.org/doc/numpy/reference/ufuncs.html
  209. # copy and paste from idx fixture as pytest doesn't support
  210. # parameters and fixtures at the same time.
  211. major_axis = Index(['foo', 'bar', 'baz', 'qux'])
  212. minor_axis = Index(['one', 'two'])
  213. major_codes = np.array([0, 0, 1, 2, 3, 3])
  214. minor_codes = np.array([0, 1, 0, 1, 0, 1])
  215. index_names = ['first', 'second']
  216. idx = MultiIndex(
  217. levels=[major_axis, minor_axis],
  218. codes=[major_codes, minor_codes],
  219. names=index_names,
  220. verify_integrity=False
  221. )
  222. if _np_version_under1p17:
  223. expected_exception = AttributeError
  224. msg = "'tuple' object has no attribute '{}'".format(func.__name__)
  225. else:
  226. expected_exception = TypeError
  227. msg = ("loop of ufunc does not support argument 0 of type tuple which"
  228. " has no callable {} method").format(func.__name__)
  229. with pytest.raises(expected_exception, match=msg):
  230. func(idx)
  231. @pytest.mark.parametrize('func', [
  232. np.isfinite, np.isinf, np.isnan, np.signbit
  233. ])
  234. def test_numpy_type_funcs(func):
  235. # for func in [np.isfinite, np.isinf, np.isnan, np.signbit]:
  236. # copy and paste from idx fixture as pytest doesn't support
  237. # parameters and fixtures at the same time.
  238. major_axis = Index(['foo', 'bar', 'baz', 'qux'])
  239. minor_axis = Index(['one', 'two'])
  240. major_codes = np.array([0, 0, 1, 2, 3, 3])
  241. minor_codes = np.array([0, 1, 0, 1, 0, 1])
  242. index_names = ['first', 'second']
  243. idx = MultiIndex(
  244. levels=[major_axis, minor_axis],
  245. codes=[major_codes, minor_codes],
  246. names=index_names,
  247. verify_integrity=False
  248. )
  249. with pytest.raises(Exception):
  250. func(idx)