test_chaining_and_caching.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import numpy as np
  2. import pytest
  3. from pandas.errors import SettingWithCopyError
  4. import pandas.util._test_decorators as td
  5. from pandas import (
  6. DataFrame,
  7. MultiIndex,
  8. Series,
  9. )
  10. import pandas._testing as tm
  11. def test_detect_chained_assignment(using_copy_on_write):
  12. # Inplace ops, originally from:
  13. # https://stackoverflow.com/questions/20508968/series-fillna-in-a-multiindex-dataframe-does-not-fill-is-this-a-bug
  14. a = [12, 23]
  15. b = [123, None]
  16. c = [1234, 2345]
  17. d = [12345, 23456]
  18. tuples = [("eyes", "left"), ("eyes", "right"), ("ears", "left"), ("ears", "right")]
  19. events = {
  20. ("eyes", "left"): a,
  21. ("eyes", "right"): b,
  22. ("ears", "left"): c,
  23. ("ears", "right"): d,
  24. }
  25. multiind = MultiIndex.from_tuples(tuples, names=["part", "side"])
  26. zed = DataFrame(events, index=["a", "b"], columns=multiind)
  27. if using_copy_on_write:
  28. zed["eyes"]["right"].fillna(value=555, inplace=True)
  29. else:
  30. msg = "A value is trying to be set on a copy of a slice from a DataFrame"
  31. with pytest.raises(SettingWithCopyError, match=msg):
  32. zed["eyes"]["right"].fillna(value=555, inplace=True)
  33. @td.skip_array_manager_invalid_test # with ArrayManager df.loc[0] is not a view
  34. def test_cache_updating(using_copy_on_write):
  35. # 5216
  36. # make sure that we don't try to set a dead cache
  37. a = np.random.rand(10, 3)
  38. df = DataFrame(a, columns=["x", "y", "z"])
  39. df_original = df.copy()
  40. tuples = [(i, j) for i in range(5) for j in range(2)]
  41. index = MultiIndex.from_tuples(tuples)
  42. df.index = index
  43. # setting via chained assignment
  44. # but actually works, since everything is a view
  45. if using_copy_on_write:
  46. with tm.raises_chained_assignment_error():
  47. df.loc[0]["z"].iloc[0] = 1.0
  48. assert df.loc[(0, 0), "z"] == df_original.loc[0, "z"]
  49. else:
  50. df.loc[0]["z"].iloc[0] = 1.0
  51. result = df.loc[(0, 0), "z"]
  52. assert result == 1
  53. # correct setting
  54. df.loc[(0, 0), "z"] = 2
  55. result = df.loc[(0, 0), "z"]
  56. assert result == 2
  57. @pytest.mark.slow
  58. def test_indexer_caching():
  59. # GH5727
  60. # make sure that indexers are in the _internal_names_set
  61. n = 1000001
  62. arrays = (range(n), range(n))
  63. index = MultiIndex.from_tuples(zip(*arrays))
  64. s = Series(np.zeros(n), index=index)
  65. str(s)
  66. # setitem
  67. expected = Series(np.ones(n), index=index)
  68. s = Series(np.zeros(n), index=index)
  69. s[s == 0] = 1
  70. tm.assert_series_equal(s, expected)