test_slice.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. from warnings import catch_warnings
  2. import numpy as np
  3. import pytest
  4. from pandas.errors import UnsortedIndexError
  5. import pandas as pd
  6. from pandas import DataFrame, Index, MultiIndex, Series, Timestamp
  7. from pandas.core.indexing import _non_reducing_slice
  8. from pandas.tests.indexing.common import _mklbl
  9. from pandas.util import testing as tm
  10. @pytest.mark.filterwarnings("ignore:\\n.ix:DeprecationWarning")
  11. class TestMultiIndexSlicers(object):
  12. def test_per_axis_per_level_getitem(self):
  13. # GH6134
  14. # example test case
  15. ix = MultiIndex.from_product([_mklbl('A', 5), _mklbl('B', 7), _mklbl(
  16. 'C', 4), _mklbl('D', 2)])
  17. df = DataFrame(np.arange(len(ix.get_values())), index=ix)
  18. result = df.loc[(slice('A1', 'A3'), slice(None), ['C1', 'C3']), :]
  19. expected = df.loc[[tuple([a, b, c, d])
  20. for a, b, c, d in df.index.values
  21. if (a == 'A1' or a == 'A2' or a == 'A3') and (
  22. c == 'C1' or c == 'C3')]]
  23. tm.assert_frame_equal(result, expected)
  24. expected = df.loc[[tuple([a, b, c, d])
  25. for a, b, c, d in df.index.values
  26. if (a == 'A1' or a == 'A2' or a == 'A3') and (
  27. c == 'C1' or c == 'C2' or c == 'C3')]]
  28. result = df.loc[(slice('A1', 'A3'), slice(None), slice('C1', 'C3')), :]
  29. tm.assert_frame_equal(result, expected)
  30. # test multi-index slicing with per axis and per index controls
  31. index = MultiIndex.from_tuples([('A', 1), ('A', 2),
  32. ('A', 3), ('B', 1)],
  33. names=['one', 'two'])
  34. columns = MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
  35. ('b', 'foo'), ('b', 'bah')],
  36. names=['lvl0', 'lvl1'])
  37. df = DataFrame(
  38. np.arange(16, dtype='int64').reshape(
  39. 4, 4), index=index, columns=columns)
  40. df = df.sort_index(axis=0).sort_index(axis=1)
  41. # identity
  42. result = df.loc[(slice(None), slice(None)), :]
  43. tm.assert_frame_equal(result, df)
  44. result = df.loc[(slice(None), slice(None)), (slice(None), slice(None))]
  45. tm.assert_frame_equal(result, df)
  46. result = df.loc[:, (slice(None), slice(None))]
  47. tm.assert_frame_equal(result, df)
  48. # index
  49. result = df.loc[(slice(None), [1]), :]
  50. expected = df.iloc[[0, 3]]
  51. tm.assert_frame_equal(result, expected)
  52. result = df.loc[(slice(None), 1), :]
  53. expected = df.iloc[[0, 3]]
  54. tm.assert_frame_equal(result, expected)
  55. # columns
  56. result = df.loc[:, (slice(None), ['foo'])]
  57. expected = df.iloc[:, [1, 3]]
  58. tm.assert_frame_equal(result, expected)
  59. # both
  60. result = df.loc[(slice(None), 1), (slice(None), ['foo'])]
  61. expected = df.iloc[[0, 3], [1, 3]]
  62. tm.assert_frame_equal(result, expected)
  63. result = df.loc['A', 'a']
  64. expected = DataFrame(dict(bar=[1, 5, 9], foo=[0, 4, 8]),
  65. index=Index([1, 2, 3], name='two'),
  66. columns=Index(['bar', 'foo'], name='lvl1'))
  67. tm.assert_frame_equal(result, expected)
  68. result = df.loc[(slice(None), [1, 2]), :]
  69. expected = df.iloc[[0, 1, 3]]
  70. tm.assert_frame_equal(result, expected)
  71. # multi-level series
  72. s = Series(np.arange(len(ix.get_values())), index=ix)
  73. result = s.loc['A1':'A3', :, ['C1', 'C3']]
  74. expected = s.loc[[tuple([a, b, c, d])
  75. for a, b, c, d in s.index.values
  76. if (a == 'A1' or a == 'A2' or a == 'A3') and (
  77. c == 'C1' or c == 'C3')]]
  78. tm.assert_series_equal(result, expected)
  79. # boolean indexers
  80. result = df.loc[(slice(None), df.loc[:, ('a', 'bar')] > 5), :]
  81. expected = df.iloc[[2, 3]]
  82. tm.assert_frame_equal(result, expected)
  83. with pytest.raises(ValueError):
  84. df.loc[(slice(None), np.array([True, False])), :]
  85. # ambiguous cases
  86. # these can be multiply interpreted (e.g. in this case
  87. # as df.loc[slice(None),[1]] as well
  88. pytest.raises(KeyError, lambda: df.loc[slice(None), [1]])
  89. result = df.loc[(slice(None), [1]), :]
  90. expected = df.iloc[[0, 3]]
  91. tm.assert_frame_equal(result, expected)
  92. # not lexsorted
  93. assert df.index.lexsort_depth == 2
  94. df = df.sort_index(level=1, axis=0)
  95. assert df.index.lexsort_depth == 0
  96. msg = ('MultiIndex slicing requires the index to be '
  97. r'lexsorted: slicing on levels \[1\], lexsort depth 0')
  98. with pytest.raises(UnsortedIndexError, match=msg):
  99. df.loc[(slice(None), slice('bar')), :]
  100. # GH 16734: not sorted, but no real slicing
  101. result = df.loc[(slice(None), df.loc[:, ('a', 'bar')] > 5), :]
  102. tm.assert_frame_equal(result, df.iloc[[1, 3], :])
  103. def test_multiindex_slicers_non_unique(self):
  104. # GH 7106
  105. # non-unique mi index support
  106. df = (DataFrame(dict(A=['foo', 'foo', 'foo', 'foo'],
  107. B=['a', 'a', 'a', 'a'],
  108. C=[1, 2, 1, 3],
  109. D=[1, 2, 3, 4]))
  110. .set_index(['A', 'B', 'C']).sort_index())
  111. assert not df.index.is_unique
  112. expected = (DataFrame(dict(A=['foo', 'foo'], B=['a', 'a'],
  113. C=[1, 1], D=[1, 3]))
  114. .set_index(['A', 'B', 'C']).sort_index())
  115. result = df.loc[(slice(None), slice(None), 1), :]
  116. tm.assert_frame_equal(result, expected)
  117. # this is equivalent of an xs expression
  118. result = df.xs(1, level=2, drop_level=False)
  119. tm.assert_frame_equal(result, expected)
  120. df = (DataFrame(dict(A=['foo', 'foo', 'foo', 'foo'],
  121. B=['a', 'a', 'a', 'a'],
  122. C=[1, 2, 1, 2],
  123. D=[1, 2, 3, 4]))
  124. .set_index(['A', 'B', 'C']).sort_index())
  125. assert not df.index.is_unique
  126. expected = (DataFrame(dict(A=['foo', 'foo'], B=['a', 'a'],
  127. C=[1, 1], D=[1, 3]))
  128. .set_index(['A', 'B', 'C']).sort_index())
  129. result = df.loc[(slice(None), slice(None), 1), :]
  130. assert not result.index.is_unique
  131. tm.assert_frame_equal(result, expected)
  132. # GH12896
  133. # numpy-implementation dependent bug
  134. ints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 16,
  135. 17, 18, 19, 200000, 200000]
  136. n = len(ints)
  137. idx = MultiIndex.from_arrays([['a'] * n, ints])
  138. result = Series([1] * n, index=idx)
  139. result = result.sort_index()
  140. result = result.loc[(slice(None), slice(100000))]
  141. expected = Series([1] * (n - 2), index=idx[:-2]).sort_index()
  142. tm.assert_series_equal(result, expected)
  143. def test_multiindex_slicers_datetimelike(self):
  144. # GH 7429
  145. # buggy/inconsistent behavior when slicing with datetime-like
  146. import datetime
  147. dates = [datetime.datetime(2012, 1, 1, 12, 12, 12) +
  148. datetime.timedelta(days=i) for i in range(6)]
  149. freq = [1, 2]
  150. index = MultiIndex.from_product(
  151. [dates, freq], names=['date', 'frequency'])
  152. df = DataFrame(
  153. np.arange(6 * 2 * 4, dtype='int64').reshape(
  154. -1, 4), index=index, columns=list('ABCD'))
  155. # multi-axis slicing
  156. idx = pd.IndexSlice
  157. expected = df.iloc[[0, 2, 4], [0, 1]]
  158. result = df.loc[(slice(Timestamp('2012-01-01 12:12:12'),
  159. Timestamp('2012-01-03 12:12:12')),
  160. slice(1, 1)), slice('A', 'B')]
  161. tm.assert_frame_equal(result, expected)
  162. result = df.loc[(idx[Timestamp('2012-01-01 12:12:12'):Timestamp(
  163. '2012-01-03 12:12:12')], idx[1:1]), slice('A', 'B')]
  164. tm.assert_frame_equal(result, expected)
  165. result = df.loc[(slice(Timestamp('2012-01-01 12:12:12'),
  166. Timestamp('2012-01-03 12:12:12')), 1),
  167. slice('A', 'B')]
  168. tm.assert_frame_equal(result, expected)
  169. # with strings
  170. result = df.loc[(slice('2012-01-01 12:12:12', '2012-01-03 12:12:12'),
  171. slice(1, 1)), slice('A', 'B')]
  172. tm.assert_frame_equal(result, expected)
  173. result = df.loc[(idx['2012-01-01 12:12:12':'2012-01-03 12:12:12'], 1),
  174. idx['A', 'B']]
  175. tm.assert_frame_equal(result, expected)
  176. def test_multiindex_slicers_edges(self):
  177. # GH 8132
  178. # various edge cases
  179. df = DataFrame(
  180. {'A': ['A0'] * 5 + ['A1'] * 5 + ['A2'] * 5,
  181. 'B': ['B0', 'B0', 'B1', 'B1', 'B2'] * 3,
  182. 'DATE': ["2013-06-11", "2013-07-02", "2013-07-09", "2013-07-30",
  183. "2013-08-06", "2013-06-11", "2013-07-02", "2013-07-09",
  184. "2013-07-30", "2013-08-06", "2013-09-03", "2013-10-01",
  185. "2013-07-09", "2013-08-06", "2013-09-03"],
  186. 'VALUES': [22, 35, 14, 9, 4, 40, 18, 4, 2, 5, 1, 2, 3, 4, 2]})
  187. df['DATE'] = pd.to_datetime(df['DATE'])
  188. df1 = df.set_index(['A', 'B', 'DATE'])
  189. df1 = df1.sort_index()
  190. # A1 - Get all values under "A0" and "A1"
  191. result = df1.loc[(slice('A1')), :]
  192. expected = df1.iloc[0:10]
  193. tm.assert_frame_equal(result, expected)
  194. # A2 - Get all values from the start to "A2"
  195. result = df1.loc[(slice('A2')), :]
  196. expected = df1
  197. tm.assert_frame_equal(result, expected)
  198. # A3 - Get all values under "B1" or "B2"
  199. result = df1.loc[(slice(None), slice('B1', 'B2')), :]
  200. expected = df1.iloc[[2, 3, 4, 7, 8, 9, 12, 13, 14]]
  201. tm.assert_frame_equal(result, expected)
  202. # A4 - Get all values between 2013-07-02 and 2013-07-09
  203. result = df1.loc[(slice(None), slice(None),
  204. slice('20130702', '20130709')), :]
  205. expected = df1.iloc[[1, 2, 6, 7, 12]]
  206. tm.assert_frame_equal(result, expected)
  207. # B1 - Get all values in B0 that are also under A0, A1 and A2
  208. result = df1.loc[(slice('A2'), slice('B0')), :]
  209. expected = df1.iloc[[0, 1, 5, 6, 10, 11]]
  210. tm.assert_frame_equal(result, expected)
  211. # B2 - Get all values in B0, B1 and B2 (similar to what #2 is doing for
  212. # the As)
  213. result = df1.loc[(slice(None), slice('B2')), :]
  214. expected = df1
  215. tm.assert_frame_equal(result, expected)
  216. # B3 - Get all values from B1 to B2 and up to 2013-08-06
  217. result = df1.loc[(slice(None), slice('B1', 'B2'),
  218. slice('2013-08-06')), :]
  219. expected = df1.iloc[[2, 3, 4, 7, 8, 9, 12, 13]]
  220. tm.assert_frame_equal(result, expected)
  221. # B4 - Same as A4 but the start of the date slice is not a key.
  222. # shows indexing on a partial selection slice
  223. result = df1.loc[(slice(None), slice(None),
  224. slice('20130701', '20130709')), :]
  225. expected = df1.iloc[[1, 2, 6, 7, 12]]
  226. tm.assert_frame_equal(result, expected)
  227. def test_per_axis_per_level_doc_examples(self):
  228. # test index maker
  229. idx = pd.IndexSlice
  230. # from indexing.rst / advanced
  231. index = MultiIndex.from_product([_mklbl('A', 4), _mklbl('B', 2),
  232. _mklbl('C', 4), _mklbl('D', 2)])
  233. columns = MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
  234. ('b', 'foo'), ('b', 'bah')],
  235. names=['lvl0', 'lvl1'])
  236. df = DataFrame(np.arange(len(index) * len(columns), dtype='int64')
  237. .reshape((len(index), len(columns))),
  238. index=index, columns=columns)
  239. result = df.loc[(slice('A1', 'A3'), slice(None), ['C1', 'C3']), :]
  240. expected = df.loc[[tuple([a, b, c, d])
  241. for a, b, c, d in df.index.values
  242. if (a == 'A1' or a == 'A2' or a == 'A3') and (
  243. c == 'C1' or c == 'C3')]]
  244. tm.assert_frame_equal(result, expected)
  245. result = df.loc[idx['A1':'A3', :, ['C1', 'C3']], :]
  246. tm.assert_frame_equal(result, expected)
  247. result = df.loc[(slice(None), slice(None), ['C1', 'C3']), :]
  248. expected = df.loc[[tuple([a, b, c, d])
  249. for a, b, c, d in df.index.values
  250. if (c == 'C1' or c == 'C3')]]
  251. tm.assert_frame_equal(result, expected)
  252. result = df.loc[idx[:, :, ['C1', 'C3']], :]
  253. tm.assert_frame_equal(result, expected)
  254. # not sorted
  255. with pytest.raises(UnsortedIndexError):
  256. df.loc['A1', ('a', slice('foo'))]
  257. # GH 16734: not sorted, but no real slicing
  258. tm.assert_frame_equal(df.loc['A1', (slice(None), 'foo')],
  259. df.loc['A1'].iloc[:, [0, 2]])
  260. df = df.sort_index(axis=1)
  261. # slicing
  262. df.loc['A1', (slice(None), 'foo')]
  263. df.loc[(slice(None), slice(None), ['C1', 'C3']), (slice(None), 'foo')]
  264. # setitem
  265. df.loc(axis=0)[:, :, ['C1', 'C3']] = -10
  266. def test_loc_axis_arguments(self):
  267. index = MultiIndex.from_product([_mklbl('A', 4), _mklbl('B', 2),
  268. _mklbl('C', 4), _mklbl('D', 2)])
  269. columns = MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
  270. ('b', 'foo'), ('b', 'bah')],
  271. names=['lvl0', 'lvl1'])
  272. df = DataFrame(np.arange(len(index) * len(columns), dtype='int64')
  273. .reshape((len(index), len(columns))),
  274. index=index,
  275. columns=columns).sort_index().sort_index(axis=1)
  276. # axis 0
  277. result = df.loc(axis=0)['A1':'A3', :, ['C1', 'C3']]
  278. expected = df.loc[[tuple([a, b, c, d])
  279. for a, b, c, d in df.index.values
  280. if (a == 'A1' or a == 'A2' or a == 'A3') and (
  281. c == 'C1' or c == 'C3')]]
  282. tm.assert_frame_equal(result, expected)
  283. result = df.loc(axis='index')[:, :, ['C1', 'C3']]
  284. expected = df.loc[[tuple([a, b, c, d])
  285. for a, b, c, d in df.index.values
  286. if (c == 'C1' or c == 'C3')]]
  287. tm.assert_frame_equal(result, expected)
  288. # axis 1
  289. result = df.loc(axis=1)[:, 'foo']
  290. expected = df.loc[:, (slice(None), 'foo')]
  291. tm.assert_frame_equal(result, expected)
  292. result = df.loc(axis='columns')[:, 'foo']
  293. expected = df.loc[:, (slice(None), 'foo')]
  294. tm.assert_frame_equal(result, expected)
  295. # invalid axis
  296. with pytest.raises(ValueError):
  297. df.loc(axis=-1)[:, :, ['C1', 'C3']]
  298. with pytest.raises(ValueError):
  299. df.loc(axis=2)[:, :, ['C1', 'C3']]
  300. with pytest.raises(ValueError):
  301. df.loc(axis='foo')[:, :, ['C1', 'C3']]
  302. def test_per_axis_per_level_setitem(self):
  303. # test index maker
  304. idx = pd.IndexSlice
  305. # test multi-index slicing with per axis and per index controls
  306. index = MultiIndex.from_tuples([('A', 1), ('A', 2),
  307. ('A', 3), ('B', 1)],
  308. names=['one', 'two'])
  309. columns = MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
  310. ('b', 'foo'), ('b', 'bah')],
  311. names=['lvl0', 'lvl1'])
  312. df_orig = DataFrame(
  313. np.arange(16, dtype='int64').reshape(
  314. 4, 4), index=index, columns=columns)
  315. df_orig = df_orig.sort_index(axis=0).sort_index(axis=1)
  316. # identity
  317. df = df_orig.copy()
  318. df.loc[(slice(None), slice(None)), :] = 100
  319. expected = df_orig.copy()
  320. expected.iloc[:, :] = 100
  321. tm.assert_frame_equal(df, expected)
  322. df = df_orig.copy()
  323. df.loc(axis=0)[:, :] = 100
  324. expected = df_orig.copy()
  325. expected.iloc[:, :] = 100
  326. tm.assert_frame_equal(df, expected)
  327. df = df_orig.copy()
  328. df.loc[(slice(None), slice(None)), (slice(None), slice(None))] = 100
  329. expected = df_orig.copy()
  330. expected.iloc[:, :] = 100
  331. tm.assert_frame_equal(df, expected)
  332. df = df_orig.copy()
  333. df.loc[:, (slice(None), slice(None))] = 100
  334. expected = df_orig.copy()
  335. expected.iloc[:, :] = 100
  336. tm.assert_frame_equal(df, expected)
  337. # index
  338. df = df_orig.copy()
  339. df.loc[(slice(None), [1]), :] = 100
  340. expected = df_orig.copy()
  341. expected.iloc[[0, 3]] = 100
  342. tm.assert_frame_equal(df, expected)
  343. df = df_orig.copy()
  344. df.loc[(slice(None), 1), :] = 100
  345. expected = df_orig.copy()
  346. expected.iloc[[0, 3]] = 100
  347. tm.assert_frame_equal(df, expected)
  348. df = df_orig.copy()
  349. df.loc(axis=0)[:, 1] = 100
  350. expected = df_orig.copy()
  351. expected.iloc[[0, 3]] = 100
  352. tm.assert_frame_equal(df, expected)
  353. # columns
  354. df = df_orig.copy()
  355. df.loc[:, (slice(None), ['foo'])] = 100
  356. expected = df_orig.copy()
  357. expected.iloc[:, [1, 3]] = 100
  358. tm.assert_frame_equal(df, expected)
  359. # both
  360. df = df_orig.copy()
  361. df.loc[(slice(None), 1), (slice(None), ['foo'])] = 100
  362. expected = df_orig.copy()
  363. expected.iloc[[0, 3], [1, 3]] = 100
  364. tm.assert_frame_equal(df, expected)
  365. df = df_orig.copy()
  366. df.loc[idx[:, 1], idx[:, ['foo']]] = 100
  367. expected = df_orig.copy()
  368. expected.iloc[[0, 3], [1, 3]] = 100
  369. tm.assert_frame_equal(df, expected)
  370. df = df_orig.copy()
  371. df.loc['A', 'a'] = 100
  372. expected = df_orig.copy()
  373. expected.iloc[0:3, 0:2] = 100
  374. tm.assert_frame_equal(df, expected)
  375. # setting with a list-like
  376. df = df_orig.copy()
  377. df.loc[(slice(None), 1), (slice(None), ['foo'])] = np.array(
  378. [[100, 100], [100, 100]], dtype='int64')
  379. expected = df_orig.copy()
  380. expected.iloc[[0, 3], [1, 3]] = 100
  381. tm.assert_frame_equal(df, expected)
  382. # not enough values
  383. df = df_orig.copy()
  384. with pytest.raises(ValueError):
  385. df.loc[(slice(None), 1), (slice(None), ['foo'])] = np.array(
  386. [[100], [100, 100]], dtype='int64')
  387. with pytest.raises(ValueError):
  388. df.loc[(slice(None), 1), (slice(None), ['foo'])] = np.array(
  389. [100, 100, 100, 100], dtype='int64')
  390. # with an alignable rhs
  391. df = df_orig.copy()
  392. df.loc[(slice(None), 1), (slice(None), ['foo'])] = df.loc[(slice(
  393. None), 1), (slice(None), ['foo'])] * 5
  394. expected = df_orig.copy()
  395. expected.iloc[[0, 3], [1, 3]] = expected.iloc[[0, 3], [1, 3]] * 5
  396. tm.assert_frame_equal(df, expected)
  397. df = df_orig.copy()
  398. df.loc[(slice(None), 1), (slice(None), ['foo'])] *= df.loc[(slice(
  399. None), 1), (slice(None), ['foo'])]
  400. expected = df_orig.copy()
  401. expected.iloc[[0, 3], [1, 3]] *= expected.iloc[[0, 3], [1, 3]]
  402. tm.assert_frame_equal(df, expected)
  403. rhs = df_orig.loc[(slice(None), 1), (slice(None), ['foo'])].copy()
  404. rhs.loc[:, ('c', 'bah')] = 10
  405. df = df_orig.copy()
  406. df.loc[(slice(None), 1), (slice(None), ['foo'])] *= rhs
  407. expected = df_orig.copy()
  408. expected.iloc[[0, 3], [1, 3]] *= expected.iloc[[0, 3], [1, 3]]
  409. tm.assert_frame_equal(df, expected)
  410. def test_multiindex_label_slicing_with_negative_step(self):
  411. s = Series(np.arange(20),
  412. MultiIndex.from_product([list('abcde'), np.arange(4)]))
  413. SLC = pd.IndexSlice
  414. def assert_slices_equivalent(l_slc, i_slc):
  415. tm.assert_series_equal(s.loc[l_slc], s.iloc[i_slc])
  416. tm.assert_series_equal(s[l_slc], s.iloc[i_slc])
  417. with catch_warnings(record=True):
  418. tm.assert_series_equal(s.ix[l_slc], s.iloc[i_slc])
  419. assert_slices_equivalent(SLC[::-1], SLC[::-1])
  420. assert_slices_equivalent(SLC['d'::-1], SLC[15::-1])
  421. assert_slices_equivalent(SLC[('d', )::-1], SLC[15::-1])
  422. assert_slices_equivalent(SLC[:'d':-1], SLC[:11:-1])
  423. assert_slices_equivalent(SLC[:('d', ):-1], SLC[:11:-1])
  424. assert_slices_equivalent(SLC['d':'b':-1], SLC[15:3:-1])
  425. assert_slices_equivalent(SLC[('d', ):'b':-1], SLC[15:3:-1])
  426. assert_slices_equivalent(SLC['d':('b', ):-1], SLC[15:3:-1])
  427. assert_slices_equivalent(SLC[('d', ):('b', ):-1], SLC[15:3:-1])
  428. assert_slices_equivalent(SLC['b':'d':-1], SLC[:0])
  429. assert_slices_equivalent(SLC[('c', 2)::-1], SLC[10::-1])
  430. assert_slices_equivalent(SLC[:('c', 2):-1], SLC[:9:-1])
  431. assert_slices_equivalent(SLC[('e', 0):('c', 2):-1], SLC[16:9:-1])
  432. def test_multiindex_slice_first_level(self):
  433. # GH 12697
  434. freq = ['a', 'b', 'c', 'd']
  435. idx = MultiIndex.from_product([freq, np.arange(500)])
  436. df = DataFrame(list(range(2000)), index=idx, columns=['Test'])
  437. df_slice = df.loc[pd.IndexSlice[:, 30:70], :]
  438. result = df_slice.loc['a']
  439. expected = DataFrame(list(range(30, 71)),
  440. columns=['Test'], index=range(30, 71))
  441. tm.assert_frame_equal(result, expected)
  442. result = df_slice.loc['d']
  443. expected = DataFrame(list(range(1530, 1571)),
  444. columns=['Test'], index=range(30, 71))
  445. tm.assert_frame_equal(result, expected)
  446. def test_int_series_slicing(
  447. self, multiindex_year_month_day_dataframe_random_data):
  448. ymd = multiindex_year_month_day_dataframe_random_data
  449. s = ymd['A']
  450. result = s[5:]
  451. expected = s.reindex(s.index[5:])
  452. tm.assert_series_equal(result, expected)
  453. exp = ymd['A'].copy()
  454. s[5:] = 0
  455. exp.values[5:] = 0
  456. tm.assert_numpy_array_equal(s.values, exp.values)
  457. result = ymd[5:]
  458. expected = ymd.reindex(s.index[5:])
  459. tm.assert_frame_equal(result, expected)
  460. def test_non_reducing_slice_on_multiindex(self):
  461. # GH 19861
  462. dic = {
  463. ('a', 'd'): [1, 4],
  464. ('a', 'c'): [2, 3],
  465. ('b', 'c'): [3, 2],
  466. ('b', 'd'): [4, 1]
  467. }
  468. df = pd.DataFrame(dic, index=[0, 1])
  469. idx = pd.IndexSlice
  470. slice_ = idx[:, idx['b', 'd']]
  471. tslice_ = _non_reducing_slice(slice_)
  472. result = df.loc[tslice_]
  473. expected = pd.DataFrame({('b', 'd'): [4, 1]})
  474. tm.assert_frame_equal(result, expected)