test_names.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # -*- coding: utf-8 -*-
  2. import pytest
  3. import pandas as pd
  4. from pandas import MultiIndex
  5. import pandas.util.testing as tm
  6. def check_level_names(index, names):
  7. assert [level.name for level in index.levels] == list(names)
  8. def test_slice_keep_name():
  9. x = MultiIndex.from_tuples([('a', 'b'), (1, 2), ('c', 'd')],
  10. names=['x', 'y'])
  11. assert x[1:].names == x.names
  12. def test_index_name_retained():
  13. # GH9857
  14. result = pd.DataFrame({'x': [1, 2, 6],
  15. 'y': [2, 2, 8],
  16. 'z': [-5, 0, 5]})
  17. result = result.set_index('z')
  18. result.loc[10] = [9, 10]
  19. df_expected = pd.DataFrame({'x': [1, 2, 6, 9],
  20. 'y': [2, 2, 8, 10],
  21. 'z': [-5, 0, 5, 10]})
  22. df_expected = df_expected.set_index('z')
  23. tm.assert_frame_equal(result, df_expected)
  24. def test_changing_names(idx):
  25. # names should be applied to levels
  26. level_names = [level.name for level in idx.levels]
  27. check_level_names(idx, idx.names)
  28. view = idx.view()
  29. copy = idx.copy()
  30. shallow_copy = idx._shallow_copy()
  31. # changing names should change level names on object
  32. new_names = [name + "a" for name in idx.names]
  33. idx.names = new_names
  34. check_level_names(idx, new_names)
  35. # but not on copies
  36. check_level_names(view, level_names)
  37. check_level_names(copy, level_names)
  38. check_level_names(shallow_copy, level_names)
  39. # and copies shouldn't change original
  40. shallow_copy.names = [name + "c" for name in shallow_copy.names]
  41. check_level_names(idx, new_names)
  42. def test_take_preserve_name(idx):
  43. taken = idx.take([3, 0, 1])
  44. assert taken.names == idx.names
  45. def test_copy_names():
  46. # Check that adding a "names" parameter to the copy is honored
  47. # GH14302
  48. multi_idx = pd.Index([(1, 2), (3, 4)], names=['MyName1', 'MyName2'])
  49. multi_idx1 = multi_idx.copy()
  50. assert multi_idx.equals(multi_idx1)
  51. assert multi_idx.names == ['MyName1', 'MyName2']
  52. assert multi_idx1.names == ['MyName1', 'MyName2']
  53. multi_idx2 = multi_idx.copy(names=['NewName1', 'NewName2'])
  54. assert multi_idx.equals(multi_idx2)
  55. assert multi_idx.names == ['MyName1', 'MyName2']
  56. assert multi_idx2.names == ['NewName1', 'NewName2']
  57. multi_idx3 = multi_idx.copy(name=['NewName1', 'NewName2'])
  58. assert multi_idx.equals(multi_idx3)
  59. assert multi_idx.names == ['MyName1', 'MyName2']
  60. assert multi_idx3.names == ['NewName1', 'NewName2']
  61. def test_names(idx, index_names):
  62. # names are assigned in setup
  63. names = index_names
  64. level_names = [level.name for level in idx.levels]
  65. assert names == level_names
  66. # setting bad names on existing
  67. index = idx
  68. with pytest.raises(ValueError, match="^Length of names"):
  69. setattr(index, "names", list(index.names) + ["third"])
  70. with pytest.raises(ValueError, match="^Length of names"):
  71. setattr(index, "names", [])
  72. # initializing with bad names (should always be equivalent)
  73. major_axis, minor_axis = idx.levels
  74. major_codes, minor_codes = idx.codes
  75. with pytest.raises(ValueError, match="^Length of names"):
  76. MultiIndex(levels=[major_axis, minor_axis],
  77. codes=[major_codes, minor_codes],
  78. names=['first'])
  79. with pytest.raises(ValueError, match="^Length of names"):
  80. MultiIndex(levels=[major_axis, minor_axis],
  81. codes=[major_codes, minor_codes],
  82. names=['first', 'second', 'third'])
  83. # names are assigned
  84. index.names = ["a", "b"]
  85. ind_names = list(index.names)
  86. level_names = [level.name for level in index.levels]
  87. assert ind_names == level_names
  88. def test_duplicate_level_names_access_raises(idx):
  89. # GH19029
  90. idx.names = ['foo', 'foo']
  91. with pytest.raises(ValueError, match='name foo occurs multiple times'):
  92. idx._get_level_number('foo')