test_partial_indexing.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import numpy as np
  2. import pytest
  3. import pandas as pd
  4. from pandas import DataFrame, MultiIndex, date_range
  5. import pandas.util.testing as tm
  6. def test_partial_string_timestamp_multiindex():
  7. # GH10331
  8. dr = pd.date_range('2016-01-01', '2016-01-03', freq='12H')
  9. abc = ['a', 'b', 'c']
  10. ix = pd.MultiIndex.from_product([dr, abc])
  11. df = pd.DataFrame({'c1': range(0, 15)}, index=ix)
  12. idx = pd.IndexSlice
  13. # c1
  14. # 2016-01-01 00:00:00 a 0
  15. # b 1
  16. # c 2
  17. # 2016-01-01 12:00:00 a 3
  18. # b 4
  19. # c 5
  20. # 2016-01-02 00:00:00 a 6
  21. # b 7
  22. # c 8
  23. # 2016-01-02 12:00:00 a 9
  24. # b 10
  25. # c 11
  26. # 2016-01-03 00:00:00 a 12
  27. # b 13
  28. # c 14
  29. # partial string matching on a single index
  30. for df_swap in (df.swaplevel(),
  31. df.swaplevel(0),
  32. df.swaplevel(0, 1)):
  33. df_swap = df_swap.sort_index()
  34. just_a = df_swap.loc['a']
  35. result = just_a.loc['2016-01-01']
  36. expected = df.loc[idx[:, 'a'], :].iloc[0:2]
  37. expected.index = expected.index.droplevel(1)
  38. tm.assert_frame_equal(result, expected)
  39. # indexing with IndexSlice
  40. result = df.loc[idx['2016-01-01':'2016-02-01', :], :]
  41. expected = df
  42. tm.assert_frame_equal(result, expected)
  43. # match on secondary index
  44. result = df_swap.loc[idx[:, '2016-01-01':'2016-01-01'], :]
  45. expected = df_swap.iloc[[0, 1, 5, 6, 10, 11]]
  46. tm.assert_frame_equal(result, expected)
  47. # Even though this syntax works on a single index, this is somewhat
  48. # ambiguous and we don't want to extend this behavior forward to work
  49. # in multi-indexes. This would amount to selecting a scalar from a
  50. # column.
  51. with pytest.raises(KeyError):
  52. df['2016-01-01']
  53. # partial string match on year only
  54. result = df.loc['2016']
  55. expected = df
  56. tm.assert_frame_equal(result, expected)
  57. # partial string match on date
  58. result = df.loc['2016-01-01']
  59. expected = df.iloc[0:6]
  60. tm.assert_frame_equal(result, expected)
  61. # partial string match on date and hour, from middle
  62. result = df.loc['2016-01-02 12']
  63. expected = df.iloc[9:12]
  64. tm.assert_frame_equal(result, expected)
  65. # partial string match on secondary index
  66. result = df_swap.loc[idx[:, '2016-01-02'], :]
  67. expected = df_swap.iloc[[2, 3, 7, 8, 12, 13]]
  68. tm.assert_frame_equal(result, expected)
  69. # tuple selector with partial string match on date
  70. result = df.loc[('2016-01-01', 'a'), :]
  71. expected = df.iloc[[0, 3]]
  72. tm.assert_frame_equal(result, expected)
  73. # Slicing date on first level should break (of course)
  74. with pytest.raises(KeyError):
  75. df_swap.loc['2016-01-01']
  76. # GH12685 (partial string with daily resolution or below)
  77. dr = date_range('2013-01-01', periods=100, freq='D')
  78. ix = MultiIndex.from_product([dr, ['a', 'b']])
  79. df = DataFrame(np.random.randn(200, 1), columns=['A'], index=ix)
  80. result = df.loc[idx['2013-03':'2013-03', :], :]
  81. expected = df.iloc[118:180]
  82. tm.assert_frame_equal(result, expected)