test_frame.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. from copy import deepcopy
  2. from operator import methodcaller
  3. import numpy as np
  4. import pytest
  5. import pandas as pd
  6. from pandas import (
  7. DataFrame,
  8. MultiIndex,
  9. Series,
  10. date_range,
  11. )
  12. import pandas._testing as tm
  13. class TestDataFrame:
  14. @pytest.mark.parametrize("func", ["_set_axis_name", "rename_axis"])
  15. def test_set_axis_name(self, func):
  16. df = DataFrame([[1, 2], [3, 4]])
  17. result = methodcaller(func, "foo")(df)
  18. assert df.index.name is None
  19. assert result.index.name == "foo"
  20. result = methodcaller(func, "cols", axis=1)(df)
  21. assert df.columns.name is None
  22. assert result.columns.name == "cols"
  23. @pytest.mark.parametrize("func", ["_set_axis_name", "rename_axis"])
  24. def test_set_axis_name_mi(self, func):
  25. df = DataFrame(
  26. np.empty((3, 3)),
  27. index=MultiIndex.from_tuples([("A", x) for x in list("aBc")]),
  28. columns=MultiIndex.from_tuples([("C", x) for x in list("xyz")]),
  29. )
  30. level_names = ["L1", "L2"]
  31. result = methodcaller(func, level_names)(df)
  32. assert result.index.names == level_names
  33. assert result.columns.names == [None, None]
  34. result = methodcaller(func, level_names, axis=1)(df)
  35. assert result.columns.names == ["L1", "L2"]
  36. assert result.index.names == [None, None]
  37. def test_nonzero_single_element(self):
  38. # allow single item via bool method
  39. msg_warn = (
  40. "DataFrame.bool is now deprecated and will be removed "
  41. "in future version of pandas"
  42. )
  43. df = DataFrame([[True]])
  44. df1 = DataFrame([[False]])
  45. with tm.assert_produces_warning(FutureWarning, match=msg_warn):
  46. assert df.bool()
  47. with tm.assert_produces_warning(FutureWarning, match=msg_warn):
  48. assert not df1.bool()
  49. df = DataFrame([[False, False]])
  50. msg_err = "The truth value of a DataFrame is ambiguous"
  51. with pytest.raises(ValueError, match=msg_err):
  52. bool(df)
  53. with tm.assert_produces_warning(FutureWarning, match=msg_warn):
  54. with pytest.raises(ValueError, match=msg_err):
  55. df.bool()
  56. def test_metadata_propagation_indiv_groupby(self):
  57. # groupby
  58. df = DataFrame(
  59. {
  60. "A": ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"],
  61. "B": ["one", "one", "two", "three", "two", "two", "one", "three"],
  62. "C": np.random.default_rng(2).standard_normal(8),
  63. "D": np.random.default_rng(2).standard_normal(8),
  64. }
  65. )
  66. result = df.groupby("A").sum()
  67. tm.assert_metadata_equivalent(df, result)
  68. def test_metadata_propagation_indiv_resample(self):
  69. # resample
  70. df = DataFrame(
  71. np.random.default_rng(2).standard_normal((1000, 2)),
  72. index=date_range("20130101", periods=1000, freq="s"),
  73. )
  74. result = df.resample("1min")
  75. tm.assert_metadata_equivalent(df, result)
  76. def test_metadata_propagation_indiv(self, monkeypatch):
  77. # merging with override
  78. # GH 6923
  79. def finalize(self, other, method=None, **kwargs):
  80. for name in self._metadata:
  81. if method == "merge":
  82. left, right = other.left, other.right
  83. value = getattr(left, name, "") + "|" + getattr(right, name, "")
  84. object.__setattr__(self, name, value)
  85. elif method == "concat":
  86. value = "+".join(
  87. [getattr(o, name) for o in other.objs if getattr(o, name, None)]
  88. )
  89. object.__setattr__(self, name, value)
  90. else:
  91. object.__setattr__(self, name, getattr(other, name, ""))
  92. return self
  93. with monkeypatch.context() as m:
  94. m.setattr(DataFrame, "_metadata", ["filename"])
  95. m.setattr(DataFrame, "__finalize__", finalize)
  96. df1 = DataFrame(
  97. np.random.default_rng(2).integers(0, 4, (3, 2)), columns=["a", "b"]
  98. )
  99. df2 = DataFrame(
  100. np.random.default_rng(2).integers(0, 4, (3, 2)), columns=["c", "d"]
  101. )
  102. DataFrame._metadata = ["filename"]
  103. df1.filename = "fname1.csv"
  104. df2.filename = "fname2.csv"
  105. result = df1.merge(df2, left_on=["a"], right_on=["c"], how="inner")
  106. assert result.filename == "fname1.csv|fname2.csv"
  107. # concat
  108. # GH#6927
  109. df1 = DataFrame(
  110. np.random.default_rng(2).integers(0, 4, (3, 2)), columns=list("ab")
  111. )
  112. df1.filename = "foo"
  113. result = pd.concat([df1, df1])
  114. assert result.filename == "foo+foo"
  115. def test_set_attribute(self):
  116. # Test for consistent setattr behavior when an attribute and a column
  117. # have the same name (Issue #8994)
  118. df = DataFrame({"x": [1, 2, 3]})
  119. df.y = 2
  120. df["y"] = [2, 4, 6]
  121. df.y = 5
  122. assert df.y == 5
  123. tm.assert_series_equal(df["y"], Series([2, 4, 6], name="y"))
  124. def test_deepcopy_empty(self):
  125. # This test covers empty frame copying with non-empty column sets
  126. # as reported in issue GH15370
  127. empty_frame = DataFrame(data=[], index=[], columns=["A"])
  128. empty_frame_copy = deepcopy(empty_frame)
  129. tm.assert_frame_equal(empty_frame_copy, empty_frame)
  130. # formerly in Generic but only test DataFrame
  131. class TestDataFrame2:
  132. @pytest.mark.parametrize("value", [1, "True", [1, 2, 3], 5.0])
  133. def test_validate_bool_args(self, value):
  134. df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
  135. msg = 'For argument "inplace" expected type bool, received type'
  136. with pytest.raises(ValueError, match=msg):
  137. df.copy().rename_axis(mapper={"a": "x", "b": "y"}, axis=1, inplace=value)
  138. with pytest.raises(ValueError, match=msg):
  139. df.copy().drop("a", axis=1, inplace=value)
  140. with pytest.raises(ValueError, match=msg):
  141. df.copy().fillna(value=0, inplace=value)
  142. with pytest.raises(ValueError, match=msg):
  143. df.copy().replace(to_replace=1, value=7, inplace=value)
  144. with pytest.raises(ValueError, match=msg):
  145. df.copy().interpolate(inplace=value)
  146. with pytest.raises(ValueError, match=msg):
  147. df.copy()._where(cond=df.a > 2, inplace=value)
  148. with pytest.raises(ValueError, match=msg):
  149. df.copy().mask(cond=df.a > 2, inplace=value)
  150. def test_unexpected_keyword(self):
  151. # GH8597
  152. df = DataFrame(
  153. np.random.default_rng(2).standard_normal((5, 2)), columns=["jim", "joe"]
  154. )
  155. ca = pd.Categorical([0, 0, 2, 2, 3, np.nan])
  156. ts = df["joe"].copy()
  157. ts[2] = np.nan
  158. msg = "unexpected keyword"
  159. with pytest.raises(TypeError, match=msg):
  160. df.drop("joe", axis=1, in_place=True)
  161. with pytest.raises(TypeError, match=msg):
  162. df.reindex([1, 0], inplace=True)
  163. with pytest.raises(TypeError, match=msg):
  164. ca.fillna(0, inplace=True)
  165. with pytest.raises(TypeError, match=msg):
  166. ts.fillna(0, in_place=True)