test_integer.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. """
  2. This file contains a minimal set of tests for compliance with the extension
  3. array interface test suite, and should contain no other tests.
  4. The test suite for the full functionality of the array is located in
  5. `pandas/tests/arrays/`.
  6. The tests in this file are inherited from the BaseExtensionTests, and only
  7. minimal tweaks should be applied to get the tests passing (by overwriting a
  8. parent method).
  9. Additional tests should either be added to one of the BaseExtensionTests
  10. classes (if they are relevant for the extension interface for all dtypes), or
  11. be added to the array-specific tests in `pandas/tests/arrays/`.
  12. """
  13. import numpy as np
  14. import pytest
  15. from pandas.core.dtypes.common import is_extension_array_dtype
  16. import pandas as pd
  17. from pandas.core.arrays import integer_array
  18. from pandas.core.arrays.integer import (
  19. Int8Dtype, Int16Dtype, Int32Dtype, Int64Dtype, UInt8Dtype, UInt16Dtype,
  20. UInt32Dtype, UInt64Dtype)
  21. from pandas.tests.extension import base
  22. def make_data():
  23. return (list(range(1, 9)) + [np.nan] + list(range(10, 98))
  24. + [np.nan] + [99, 100])
  25. @pytest.fixture(params=[Int8Dtype, Int16Dtype, Int32Dtype, Int64Dtype,
  26. UInt8Dtype, UInt16Dtype, UInt32Dtype, UInt64Dtype])
  27. def dtype(request):
  28. return request.param()
  29. @pytest.fixture
  30. def data(dtype):
  31. return integer_array(make_data(), dtype=dtype)
  32. @pytest.fixture
  33. def data_missing(dtype):
  34. return integer_array([np.nan, 1], dtype=dtype)
  35. @pytest.fixture
  36. def data_for_sorting(dtype):
  37. return integer_array([1, 2, 0], dtype=dtype)
  38. @pytest.fixture
  39. def data_missing_for_sorting(dtype):
  40. return integer_array([1, np.nan, 0], dtype=dtype)
  41. @pytest.fixture
  42. def na_cmp():
  43. # we are np.nan
  44. return lambda x, y: np.isnan(x) and np.isnan(y)
  45. @pytest.fixture
  46. def na_value():
  47. return np.nan
  48. @pytest.fixture
  49. def data_for_grouping(dtype):
  50. b = 1
  51. a = 0
  52. c = 2
  53. na = np.nan
  54. return integer_array([b, b, na, na, a, a, b, c], dtype=dtype)
  55. class TestDtype(base.BaseDtypeTests):
  56. @pytest.mark.skip(reason="using multiple dtypes")
  57. def test_is_dtype_unboxes_dtype(self):
  58. # we have multiple dtypes, so skip
  59. pass
  60. class TestArithmeticOps(base.BaseArithmeticOpsTests):
  61. def check_opname(self, s, op_name, other, exc=None):
  62. # overwriting to indicate ops don't raise an error
  63. super(TestArithmeticOps, self).check_opname(s, op_name,
  64. other, exc=None)
  65. def _check_op(self, s, op, other, op_name, exc=NotImplementedError):
  66. if exc is None:
  67. if s.dtype.is_unsigned_integer and (op_name == '__rsub__'):
  68. # TODO see https://github.com/pandas-dev/pandas/issues/22023
  69. pytest.skip("unsigned subtraction gives negative values")
  70. if (hasattr(other, 'dtype')
  71. and not is_extension_array_dtype(other.dtype)
  72. and pd.api.types.is_integer_dtype(other.dtype)):
  73. # other is np.int64 and would therefore always result in
  74. # upcasting, so keeping other as same numpy_dtype
  75. other = other.astype(s.dtype.numpy_dtype)
  76. result = op(s, other)
  77. expected = s.combine(other, op)
  78. if op_name == '__rdiv__':
  79. # combine is not giving the correct result for this case
  80. pytest.skip("skipping reverse div in python 2")
  81. elif op_name in ('__rtruediv__', '__truediv__', '__div__'):
  82. expected = expected.astype(float)
  83. if op_name == '__rtruediv__':
  84. # TODO reverse operators result in object dtype
  85. result = result.astype(float)
  86. elif op_name.startswith('__r'):
  87. # TODO reverse operators result in object dtype
  88. # see https://github.com/pandas-dev/pandas/issues/22024
  89. expected = expected.astype(s.dtype)
  90. result = result.astype(s.dtype)
  91. else:
  92. # combine method result in 'biggest' (int64) dtype
  93. expected = expected.astype(s.dtype)
  94. pass
  95. if (op_name == '__rpow__') and isinstance(other, pd.Series):
  96. # TODO pow on Int arrays gives different result with NA
  97. # see https://github.com/pandas-dev/pandas/issues/22022
  98. result = result.fillna(1)
  99. self.assert_series_equal(result, expected)
  100. else:
  101. with pytest.raises(exc):
  102. op(s, other)
  103. def _check_divmod_op(self, s, op, other, exc=None):
  104. super(TestArithmeticOps, self)._check_divmod_op(s, op, other, None)
  105. @pytest.mark.skip(reason="intNA does not error on ops")
  106. def test_error(self, data, all_arithmetic_operators):
  107. # other specific errors tested in the integer array specific tests
  108. pass
  109. class TestComparisonOps(base.BaseComparisonOpsTests):
  110. def check_opname(self, s, op_name, other, exc=None):
  111. super(TestComparisonOps, self).check_opname(s, op_name,
  112. other, exc=None)
  113. def _compare_other(self, s, data, op_name, other):
  114. self.check_opname(s, op_name, other)
  115. class TestInterface(base.BaseInterfaceTests):
  116. pass
  117. class TestConstructors(base.BaseConstructorsTests):
  118. pass
  119. class TestReshaping(base.BaseReshapingTests):
  120. pass
  121. # for test_concat_mixed_dtypes test
  122. # concat of an Integer and Int coerces to object dtype
  123. # TODO(jreback) once integrated this would
  124. class TestGetitem(base.BaseGetitemTests):
  125. pass
  126. class TestSetitem(base.BaseSetitemTests):
  127. pass
  128. class TestMissing(base.BaseMissingTests):
  129. pass
  130. class TestMethods(base.BaseMethodsTests):
  131. @pytest.mark.parametrize('dropna', [True, False])
  132. def test_value_counts(self, all_data, dropna):
  133. all_data = all_data[:10]
  134. if dropna:
  135. other = np.array(all_data[~all_data.isna()])
  136. else:
  137. other = all_data
  138. result = pd.Series(all_data).value_counts(dropna=dropna).sort_index()
  139. expected = pd.Series(other).value_counts(
  140. dropna=dropna).sort_index()
  141. expected.index = expected.index.astype(all_data.dtype)
  142. self.assert_series_equal(result, expected)
  143. class TestCasting(base.BaseCastingTests):
  144. pass
  145. class TestGroupby(base.BaseGroupbyTests):
  146. pass
  147. class TestNumericReduce(base.BaseNumericReduceTests):
  148. pass
  149. class TestBooleanReduce(base.BaseBooleanReduceTests):
  150. pass
  151. class TestPrinting(base.BasePrintingTests):
  152. pass
  153. class TestParsing(base.BaseParsingTests):
  154. pass