test_iloc.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import numpy as np
  2. import pytest
  3. from pandas import (
  4. DataFrame,
  5. MultiIndex,
  6. Series,
  7. )
  8. import pandas._testing as tm
  9. @pytest.fixture
  10. def simple_multiindex_dataframe():
  11. """
  12. Factory function to create simple 3 x 3 dataframe with
  13. both columns and row MultiIndex using supplied data or
  14. random data by default.
  15. """
  16. data = np.random.randn(3, 3)
  17. return DataFrame(
  18. data, columns=[[2, 2, 4], [6, 8, 10]], index=[[4, 4, 8], [8, 10, 12]]
  19. )
  20. @pytest.mark.parametrize(
  21. "indexer, expected",
  22. [
  23. (
  24. lambda df: df.iloc[0],
  25. lambda arr: Series(arr[0], index=[[2, 2, 4], [6, 8, 10]], name=(4, 8)),
  26. ),
  27. (
  28. lambda df: df.iloc[2],
  29. lambda arr: Series(arr[2], index=[[2, 2, 4], [6, 8, 10]], name=(8, 12)),
  30. ),
  31. (
  32. lambda df: df.iloc[:, 2],
  33. lambda arr: Series(arr[:, 2], index=[[4, 4, 8], [8, 10, 12]], name=(4, 10)),
  34. ),
  35. ],
  36. )
  37. def test_iloc_returns_series(indexer, expected, simple_multiindex_dataframe):
  38. df = simple_multiindex_dataframe
  39. arr = df.values
  40. result = indexer(df)
  41. expected = expected(arr)
  42. tm.assert_series_equal(result, expected)
  43. def test_iloc_returns_dataframe(simple_multiindex_dataframe):
  44. df = simple_multiindex_dataframe
  45. result = df.iloc[[0, 1]]
  46. expected = df.xs(4, drop_level=False)
  47. tm.assert_frame_equal(result, expected)
  48. def test_iloc_returns_scalar(simple_multiindex_dataframe):
  49. df = simple_multiindex_dataframe
  50. arr = df.values
  51. result = df.iloc[2, 2]
  52. expected = arr[2, 2]
  53. assert result == expected
  54. def test_iloc_getitem_multiple_items():
  55. # GH 5528
  56. tup = zip(*[["a", "a", "b", "b"], ["x", "y", "x", "y"]])
  57. index = MultiIndex.from_tuples(tup)
  58. df = DataFrame(np.random.randn(4, 4), index=index)
  59. result = df.iloc[[2, 3]]
  60. expected = df.xs("b", drop_level=False)
  61. tm.assert_frame_equal(result, expected)
  62. def test_iloc_getitem_labels():
  63. # this is basically regular indexing
  64. arr = np.random.randn(4, 3)
  65. df = DataFrame(
  66. arr,
  67. columns=[["i", "i", "j"], ["A", "A", "B"]],
  68. index=[["i", "i", "j", "k"], ["X", "X", "Y", "Y"]],
  69. )
  70. result = df.iloc[2, 2]
  71. expected = arr[2, 2]
  72. assert result == expected
  73. def test_frame_getitem_slice(multiindex_dataframe_random_data):
  74. df = multiindex_dataframe_random_data
  75. result = df.iloc[:4]
  76. expected = df[:4]
  77. tm.assert_frame_equal(result, expected)
  78. def test_frame_setitem_slice(multiindex_dataframe_random_data):
  79. df = multiindex_dataframe_random_data
  80. df.iloc[:4] = 0
  81. assert (df.values[:4] == 0).all()
  82. assert (df.values[4:] != 0).all()
  83. def test_indexing_ambiguity_bug_1678():
  84. # GH 1678
  85. columns = MultiIndex.from_tuples(
  86. [("Ohio", "Green"), ("Ohio", "Red"), ("Colorado", "Green")]
  87. )
  88. index = MultiIndex.from_tuples([("a", 1), ("a", 2), ("b", 1), ("b", 2)])
  89. df = DataFrame(np.arange(12).reshape((4, 3)), index=index, columns=columns)
  90. result = df.iloc[:, 1]
  91. expected = df.loc[:, ("Ohio", "Red")]
  92. tm.assert_series_equal(result, expected)
  93. def test_iloc_integer_locations():
  94. # GH 13797
  95. data = [
  96. ["str00", "str01"],
  97. ["str10", "str11"],
  98. ["str20", "srt21"],
  99. ["str30", "str31"],
  100. ["str40", "str41"],
  101. ]
  102. index = MultiIndex.from_tuples(
  103. [("CC", "A"), ("CC", "B"), ("CC", "B"), ("BB", "a"), ("BB", "b")]
  104. )
  105. expected = DataFrame(data)
  106. df = DataFrame(data, index=index)
  107. result = DataFrame([[df.iloc[r, c] for c in range(2)] for r in range(5)])
  108. tm.assert_frame_equal(result, expected)
  109. @pytest.mark.parametrize(
  110. "data, indexes, values, expected_k",
  111. [
  112. # test without indexer value in first level of MultiIndex
  113. ([[2, 22, 5], [2, 33, 6]], [0, -1, 1], [2, 3, 1], [7, 10]),
  114. # test like code sample 1 in the issue
  115. ([[1, 22, 555], [1, 33, 666]], [0, -1, 1], [200, 300, 100], [755, 1066]),
  116. # test like code sample 2 in the issue
  117. ([[1, 3, 7], [2, 4, 8]], [0, -1, 1], [10, 10, 1000], [17, 1018]),
  118. # test like code sample 3 in the issue
  119. ([[1, 11, 4], [2, 22, 5], [3, 33, 6]], [0, -1, 1], [4, 7, 10], [8, 15, 13]),
  120. ],
  121. )
  122. def test_iloc_setitem_int_multiindex_series(data, indexes, values, expected_k):
  123. # GH17148
  124. df = DataFrame(data=data, columns=["i", "j", "k"])
  125. df = df.set_index(["i", "j"])
  126. series = df.k.copy()
  127. for i, v in zip(indexes, values):
  128. series.iloc[i] += v
  129. df["k"] = expected_k
  130. expected = df.k
  131. tm.assert_series_equal(series, expected)
  132. def test_getitem_iloc(multiindex_dataframe_random_data):
  133. df = multiindex_dataframe_random_data
  134. result = df.iloc[2]
  135. expected = df.xs(df.index[2])
  136. tm.assert_series_equal(result, expected)