test_numpy.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. """
  2. Additional tests for PandasArray that aren't covered by
  3. the interface tests.
  4. """
  5. import numpy as np
  6. import pytest
  7. import pandas.util._test_decorators as td
  8. import pandas as pd
  9. from pandas import compat
  10. from pandas.arrays import PandasArray
  11. from pandas.core.arrays.numpy_ import PandasDtype
  12. import pandas.util.testing as tm
  13. @pytest.fixture(params=[
  14. np.array(['a', 'b'], dtype=object),
  15. np.array([0, 1], dtype=float),
  16. np.array([0, 1], dtype=int),
  17. np.array([0, 1 + 2j], dtype=complex),
  18. np.array([True, False], dtype=bool),
  19. np.array([0, 1], dtype='datetime64[ns]'),
  20. np.array([0, 1], dtype='timedelta64[ns]'),
  21. ])
  22. def any_numpy_array(request):
  23. """
  24. Parametrized fixture for NumPy arrays with different dtypes.
  25. This excludes string and bytes.
  26. """
  27. return request.param
  28. # ----------------------------------------------------------------------------
  29. # PandasDtype
  30. @pytest.mark.parametrize('dtype, expected', [
  31. ('bool', True),
  32. ('int', True),
  33. ('uint', True),
  34. ('float', True),
  35. ('complex', True),
  36. ('str', False),
  37. pytest.param('bytes', False,
  38. marks=pytest.mark.skipif(compat.PY2, reason="PY2")),
  39. ('datetime64[ns]', False),
  40. ('object', False),
  41. ('void', False),
  42. ])
  43. def test_is_numeric(dtype, expected):
  44. dtype = PandasDtype(dtype)
  45. assert dtype._is_numeric is expected
  46. @pytest.mark.parametrize('dtype, expected', [
  47. ('bool', True),
  48. ('int', False),
  49. ('uint', False),
  50. ('float', False),
  51. ('complex', False),
  52. ('str', False),
  53. pytest.param('bytes', False,
  54. marks=pytest.mark.skipif(compat.PY2, reason="PY2")),
  55. ('datetime64[ns]', False),
  56. ('object', False),
  57. ('void', False)
  58. ])
  59. def test_is_boolean(dtype, expected):
  60. dtype = PandasDtype(dtype)
  61. assert dtype._is_boolean is expected
  62. def test_repr():
  63. dtype = PandasDtype(np.dtype("int64"))
  64. assert repr(dtype) == "PandasDtype('int64')"
  65. def test_constructor_from_string():
  66. result = PandasDtype.construct_from_string("int64")
  67. expected = PandasDtype(np.dtype("int64"))
  68. assert result == expected
  69. # ----------------------------------------------------------------------------
  70. # Construction
  71. def test_constructor_no_coercion():
  72. with pytest.raises(ValueError, match='NumPy array'):
  73. PandasArray([1, 2, 3])
  74. def test_series_constructor_with_copy():
  75. ndarray = np.array([1, 2, 3])
  76. ser = pd.Series(PandasArray(ndarray), copy=True)
  77. assert ser.values is not ndarray
  78. def test_series_constructor_with_astype():
  79. ndarray = np.array([1, 2, 3])
  80. result = pd.Series(PandasArray(ndarray), dtype="float64")
  81. expected = pd.Series([1.0, 2.0, 3.0], dtype="float64")
  82. tm.assert_series_equal(result, expected)
  83. def test_from_sequence_dtype():
  84. arr = np.array([1, 2, 3], dtype='int64')
  85. result = PandasArray._from_sequence(arr, dtype='uint64')
  86. expected = PandasArray(np.array([1, 2, 3], dtype='uint64'))
  87. tm.assert_extension_array_equal(result, expected)
  88. def test_constructor_copy():
  89. arr = np.array([0, 1])
  90. result = PandasArray(arr, copy=True)
  91. assert np.shares_memory(result._ndarray, arr) is False
  92. def test_constructor_with_data(any_numpy_array):
  93. nparr = any_numpy_array
  94. arr = PandasArray(nparr)
  95. assert arr.dtype.numpy_dtype == nparr.dtype
  96. # ----------------------------------------------------------------------------
  97. # Conversion
  98. def test_to_numpy():
  99. arr = PandasArray(np.array([1, 2, 3]))
  100. result = arr.to_numpy()
  101. assert result is arr._ndarray
  102. result = arr.to_numpy(copy=True)
  103. assert result is not arr._ndarray
  104. result = arr.to_numpy(dtype='f8')
  105. expected = np.array([1, 2, 3], dtype='f8')
  106. tm.assert_numpy_array_equal(result, expected)
  107. # ----------------------------------------------------------------------------
  108. # Setitem
  109. def test_setitem_series():
  110. ser = pd.Series([1, 2, 3])
  111. ser.array[0] = 10
  112. expected = pd.Series([10, 2, 3])
  113. tm.assert_series_equal(ser, expected)
  114. def test_setitem(any_numpy_array):
  115. nparr = any_numpy_array
  116. arr = PandasArray(nparr, copy=True)
  117. arr[0] = arr[1]
  118. nparr[0] = nparr[1]
  119. tm.assert_numpy_array_equal(arr.to_numpy(), nparr)
  120. # ----------------------------------------------------------------------------
  121. # Reductions
  122. def test_bad_reduce_raises():
  123. arr = np.array([1, 2, 3], dtype='int64')
  124. arr = PandasArray(arr)
  125. msg = "cannot perform not_a_method with type int"
  126. with pytest.raises(TypeError, match=msg):
  127. arr._reduce(msg)
  128. def test_validate_reduction_keyword_args():
  129. arr = PandasArray(np.array([1, 2, 3]))
  130. msg = "the 'keepdims' parameter is not supported .*all"
  131. with pytest.raises(ValueError, match=msg):
  132. arr.all(keepdims=True)
  133. # ----------------------------------------------------------------------------
  134. # Ops
  135. @td.skip_if_no("numpy", min_version="1.13.0")
  136. def test_ufunc():
  137. arr = PandasArray(np.array([-1.0, 0.0, 1.0]))
  138. result = np.abs(arr)
  139. expected = PandasArray(np.abs(arr._ndarray))
  140. tm.assert_extension_array_equal(result, expected)
  141. r1, r2 = np.divmod(arr, np.add(arr, 2))
  142. e1, e2 = np.divmod(arr._ndarray, np.add(arr._ndarray, 2))
  143. e1 = PandasArray(e1)
  144. e2 = PandasArray(e2)
  145. tm.assert_extension_array_equal(r1, e1)
  146. tm.assert_extension_array_equal(r2, e2)
  147. @td.skip_if_no("numpy", min_version="1.13.0")
  148. def test_basic_binop():
  149. # Just a basic smoke test. The EA interface tests exercise this
  150. # more thoroughly.
  151. x = PandasArray(np.array([1, 2, 3]))
  152. result = x + x
  153. expected = PandasArray(np.array([2, 4, 6]))
  154. tm.assert_extension_array_equal(result, expected)