test_update.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import numpy as np
  2. import pytest
  3. from pandas.compat import WARNING_CHECK_DISABLED
  4. import pandas.util._test_decorators as td
  5. from pandas import (
  6. CategoricalDtype,
  7. DataFrame,
  8. NaT,
  9. Series,
  10. Timestamp,
  11. )
  12. import pandas._testing as tm
  13. class TestUpdate:
  14. def test_update(self, using_copy_on_write):
  15. s = Series([1.5, np.nan, 3.0, 4.0, np.nan])
  16. s2 = Series([np.nan, 3.5, np.nan, 5.0])
  17. s.update(s2)
  18. expected = Series([1.5, 3.5, 3.0, 5.0, np.nan])
  19. tm.assert_series_equal(s, expected)
  20. # GH 3217
  21. df = DataFrame([{"a": 1}, {"a": 3, "b": 2}])
  22. df["c"] = np.nan
  23. # Cast to object to avoid upcast when setting "foo"
  24. df["c"] = df["c"].astype(object)
  25. df_orig = df.copy()
  26. if using_copy_on_write:
  27. with tm.raises_chained_assignment_error():
  28. df["c"].update(Series(["foo"], index=[0]))
  29. expected = df_orig
  30. else:
  31. with tm.assert_produces_warning(
  32. FutureWarning if not WARNING_CHECK_DISABLED else None,
  33. match="inplace method",
  34. ):
  35. df["c"].update(Series(["foo"], index=[0]))
  36. expected = DataFrame(
  37. [[1, np.nan, "foo"], [3, 2.0, np.nan]], columns=["a", "b", "c"]
  38. )
  39. expected["c"] = expected["c"].astype(object)
  40. tm.assert_frame_equal(df, expected)
  41. @pytest.mark.parametrize(
  42. "other, dtype, expected, warn",
  43. [
  44. # other is int
  45. ([61, 63], "int32", Series([10, 61, 12], dtype="int32"), None),
  46. ([61, 63], "int64", Series([10, 61, 12]), None),
  47. ([61, 63], float, Series([10.0, 61.0, 12.0]), None),
  48. ([61, 63], object, Series([10, 61, 12], dtype=object), None),
  49. # other is float, but can be cast to int
  50. ([61.0, 63.0], "int32", Series([10, 61, 12], dtype="int32"), None),
  51. ([61.0, 63.0], "int64", Series([10, 61, 12]), None),
  52. ([61.0, 63.0], float, Series([10.0, 61.0, 12.0]), None),
  53. ([61.0, 63.0], object, Series([10, 61.0, 12], dtype=object), None),
  54. # others is float, cannot be cast to int
  55. ([61.1, 63.1], "int32", Series([10.0, 61.1, 12.0]), FutureWarning),
  56. ([61.1, 63.1], "int64", Series([10.0, 61.1, 12.0]), FutureWarning),
  57. ([61.1, 63.1], float, Series([10.0, 61.1, 12.0]), None),
  58. ([61.1, 63.1], object, Series([10, 61.1, 12], dtype=object), None),
  59. # other is object, cannot be cast
  60. ([(61,), (63,)], "int32", Series([10, (61,), 12]), FutureWarning),
  61. ([(61,), (63,)], "int64", Series([10, (61,), 12]), FutureWarning),
  62. ([(61,), (63,)], float, Series([10.0, (61,), 12.0]), FutureWarning),
  63. ([(61,), (63,)], object, Series([10, (61,), 12]), None),
  64. ],
  65. )
  66. def test_update_dtypes(self, other, dtype, expected, warn):
  67. ser = Series([10, 11, 12], dtype=dtype)
  68. other = Series(other, index=[1, 3])
  69. with tm.assert_produces_warning(warn, match="item of incompatible dtype"):
  70. ser.update(other)
  71. tm.assert_series_equal(ser, expected)
  72. @pytest.mark.parametrize(
  73. "series, other, expected",
  74. [
  75. # update by key
  76. (
  77. Series({"a": 1, "b": 2, "c": 3, "d": 4}),
  78. {"b": 5, "c": np.nan},
  79. Series({"a": 1, "b": 5, "c": 3, "d": 4}),
  80. ),
  81. # update by position
  82. (Series([1, 2, 3, 4]), [np.nan, 5, 1], Series([1, 5, 1, 4])),
  83. ],
  84. )
  85. def test_update_from_non_series(self, series, other, expected):
  86. # GH 33215
  87. series.update(other)
  88. tm.assert_series_equal(series, expected)
  89. @pytest.mark.parametrize(
  90. "data, other, expected, dtype",
  91. [
  92. (["a", None], [None, "b"], ["a", "b"], "string[python]"),
  93. pytest.param(
  94. ["a", None],
  95. [None, "b"],
  96. ["a", "b"],
  97. "string[pyarrow]",
  98. marks=td.skip_if_no("pyarrow"),
  99. ),
  100. ([1, None], [None, 2], [1, 2], "Int64"),
  101. ([True, None], [None, False], [True, False], "boolean"),
  102. (
  103. ["a", None],
  104. [None, "b"],
  105. ["a", "b"],
  106. CategoricalDtype(categories=["a", "b"]),
  107. ),
  108. (
  109. [Timestamp(year=2020, month=1, day=1, tz="Europe/London"), NaT],
  110. [NaT, Timestamp(year=2020, month=1, day=1, tz="Europe/London")],
  111. [Timestamp(year=2020, month=1, day=1, tz="Europe/London")] * 2,
  112. "datetime64[ns, Europe/London]",
  113. ),
  114. ],
  115. )
  116. def test_update_extension_array_series(self, data, other, expected, dtype):
  117. result = Series(data, dtype=dtype)
  118. other = Series(other, dtype=dtype)
  119. expected = Series(expected, dtype=dtype)
  120. result.update(other)
  121. tm.assert_series_equal(result, expected)
  122. def test_update_with_categorical_type(self):
  123. # GH 25744
  124. dtype = CategoricalDtype(["a", "b", "c", "d"])
  125. s1 = Series(["a", "b", "c"], index=[1, 2, 3], dtype=dtype)
  126. s2 = Series(["b", "a"], index=[1, 2], dtype=dtype)
  127. s1.update(s2)
  128. result = s1
  129. expected = Series(["b", "a", "c"], index=[1, 2, 3], dtype=dtype)
  130. tm.assert_series_equal(result, expected)