test_unary.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. from decimal import Decimal
  2. import numpy as np
  3. import pytest
  4. from pandas.compat.numpy import np_version_gte1p25
  5. import pandas as pd
  6. import pandas._testing as tm
  7. class TestDataFrameUnaryOperators:
  8. # __pos__, __neg__, __invert__
  9. @pytest.mark.parametrize(
  10. "df,expected",
  11. [
  12. (pd.DataFrame({"a": [-1, 1]}), pd.DataFrame({"a": [1, -1]})),
  13. (pd.DataFrame({"a": [False, True]}), pd.DataFrame({"a": [True, False]})),
  14. (
  15. pd.DataFrame({"a": pd.Series(pd.to_timedelta([-1, 1]))}),
  16. pd.DataFrame({"a": pd.Series(pd.to_timedelta([1, -1]))}),
  17. ),
  18. ],
  19. )
  20. def test_neg_numeric(self, df, expected):
  21. tm.assert_frame_equal(-df, expected)
  22. tm.assert_series_equal(-df["a"], expected["a"])
  23. @pytest.mark.parametrize(
  24. "df, expected",
  25. [
  26. (np.array([1, 2], dtype=object), np.array([-1, -2], dtype=object)),
  27. ([Decimal("1.0"), Decimal("2.0")], [Decimal("-1.0"), Decimal("-2.0")]),
  28. ],
  29. )
  30. def test_neg_object(self, df, expected):
  31. # GH#21380
  32. df = pd.DataFrame({"a": df})
  33. expected = pd.DataFrame({"a": expected})
  34. tm.assert_frame_equal(-df, expected)
  35. tm.assert_series_equal(-df["a"], expected["a"])
  36. @pytest.mark.parametrize(
  37. "df",
  38. [
  39. pd.DataFrame({"a": ["a", "b"]}),
  40. pd.DataFrame({"a": pd.to_datetime(["2017-01-22", "1970-01-01"])}),
  41. ],
  42. )
  43. def test_neg_raises(self, df):
  44. msg = (
  45. "bad operand type for unary -: 'str'|"
  46. r"bad operand type for unary -: 'DatetimeArray'"
  47. )
  48. with pytest.raises(TypeError, match=msg):
  49. (-df)
  50. with pytest.raises(TypeError, match=msg):
  51. (-df["a"])
  52. def test_invert(self, float_frame):
  53. df = float_frame
  54. tm.assert_frame_equal(-(df < 0), ~(df < 0))
  55. def test_invert_mixed(self):
  56. shape = (10, 5)
  57. df = pd.concat(
  58. [
  59. pd.DataFrame(np.zeros(shape, dtype="bool")),
  60. pd.DataFrame(np.zeros(shape, dtype=int)),
  61. ],
  62. axis=1,
  63. ignore_index=True,
  64. )
  65. result = ~df
  66. expected = pd.concat(
  67. [
  68. pd.DataFrame(np.ones(shape, dtype="bool")),
  69. pd.DataFrame(-np.ones(shape, dtype=int)),
  70. ],
  71. axis=1,
  72. ignore_index=True,
  73. )
  74. tm.assert_frame_equal(result, expected)
  75. def test_invert_empy_not_input(self):
  76. # GH#51032
  77. df = pd.DataFrame()
  78. result = ~df
  79. tm.assert_frame_equal(df, result)
  80. assert df is not result
  81. @pytest.mark.parametrize(
  82. "df",
  83. [
  84. pd.DataFrame({"a": [-1, 1]}),
  85. pd.DataFrame({"a": [False, True]}),
  86. pd.DataFrame({"a": pd.Series(pd.to_timedelta([-1, 1]))}),
  87. ],
  88. )
  89. def test_pos_numeric(self, df):
  90. # GH#16073
  91. tm.assert_frame_equal(+df, df)
  92. tm.assert_series_equal(+df["a"], df["a"])
  93. @pytest.mark.parametrize(
  94. "df",
  95. [
  96. pd.DataFrame({"a": np.array([-1, 2], dtype=object)}),
  97. pd.DataFrame({"a": [Decimal("-1.0"), Decimal("2.0")]}),
  98. ],
  99. )
  100. def test_pos_object(self, df):
  101. # GH#21380
  102. tm.assert_frame_equal(+df, df)
  103. tm.assert_series_equal(+df["a"], df["a"])
  104. @pytest.mark.parametrize(
  105. "df",
  106. [
  107. pytest.param(
  108. pd.DataFrame({"a": ["a", "b"]}),
  109. # filterwarnings removable once min numpy version is 1.25
  110. marks=[
  111. pytest.mark.filterwarnings("ignore:Applying:DeprecationWarning")
  112. ],
  113. ),
  114. ],
  115. )
  116. def test_pos_object_raises(self, df):
  117. # GH#21380
  118. if np_version_gte1p25:
  119. with pytest.raises(
  120. TypeError, match=r"^bad operand type for unary \+: \'str\'$"
  121. ):
  122. tm.assert_frame_equal(+df, df)
  123. else:
  124. tm.assert_series_equal(+df["a"], df["a"])
  125. @pytest.mark.parametrize(
  126. "df", [pd.DataFrame({"a": pd.to_datetime(["2017-01-22", "1970-01-01"])})]
  127. )
  128. def test_pos_raises(self, df):
  129. msg = r"bad operand type for unary \+: 'DatetimeArray'"
  130. with pytest.raises(TypeError, match=msg):
  131. (+df)
  132. with pytest.raises(TypeError, match=msg):
  133. (+df["a"])
  134. def test_unary_nullable(self):
  135. df = pd.DataFrame(
  136. {
  137. "a": pd.array([1, -2, 3, pd.NA], dtype="Int64"),
  138. "b": pd.array([4.0, -5.0, 6.0, pd.NA], dtype="Float32"),
  139. "c": pd.array([True, False, False, pd.NA], dtype="boolean"),
  140. # include numpy bool to make sure bool-vs-boolean behavior
  141. # is consistent in non-NA locations
  142. "d": np.array([True, False, False, True]),
  143. }
  144. )
  145. result = +df
  146. res_ufunc = np.positive(df)
  147. expected = df
  148. # TODO: assert that we have copies?
  149. tm.assert_frame_equal(result, expected)
  150. tm.assert_frame_equal(res_ufunc, expected)
  151. result = -df
  152. res_ufunc = np.negative(df)
  153. expected = pd.DataFrame(
  154. {
  155. "a": pd.array([-1, 2, -3, pd.NA], dtype="Int64"),
  156. "b": pd.array([-4.0, 5.0, -6.0, pd.NA], dtype="Float32"),
  157. "c": pd.array([False, True, True, pd.NA], dtype="boolean"),
  158. "d": np.array([False, True, True, False]),
  159. }
  160. )
  161. tm.assert_frame_equal(result, expected)
  162. tm.assert_frame_equal(res_ufunc, expected)
  163. result = abs(df)
  164. res_ufunc = np.abs(df)
  165. expected = pd.DataFrame(
  166. {
  167. "a": pd.array([1, 2, 3, pd.NA], dtype="Int64"),
  168. "b": pd.array([4.0, 5.0, 6.0, pd.NA], dtype="Float32"),
  169. "c": pd.array([True, False, False, pd.NA], dtype="boolean"),
  170. "d": np.array([True, False, False, True]),
  171. }
  172. )
  173. tm.assert_frame_equal(result, expected)
  174. tm.assert_frame_equal(res_ufunc, expected)