PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/pandas/sparse/tests/test_arithmetics.py

http://github.com/wesm/pandas
Python | 347 lines | 246 code | 88 blank | 13 comment | 13 complexity | 5113a2a5a7067c02161e7eb70180cae3 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. import numpy as np
  2. import pandas as pd
  3. import pandas.util.testing as tm
  4. class TestSparseArrayArithmetics(tm.TestCase):
  5. _multiprocess_can_split_ = True
  6. _base = np.array
  7. _klass = pd.SparseArray
  8. def _assert(self, a, b):
  9. tm.assert_numpy_array_equal(a, b)
  10. def _check_numeric_ops(self, a, b, a_dense, b_dense):
  11. # sparse & sparse
  12. self._assert((a + b).to_dense(), a_dense + b_dense)
  13. self._assert((b + a).to_dense(), b_dense + a_dense)
  14. self._assert((a - b).to_dense(), a_dense - b_dense)
  15. self._assert((b - a).to_dense(), b_dense - a_dense)
  16. self._assert((a * b).to_dense(), a_dense * b_dense)
  17. self._assert((b * a).to_dense(), b_dense * a_dense)
  18. # pandas uses future division
  19. self._assert((a / b).to_dense(), a_dense * 1.0 / b_dense)
  20. self._assert((b / a).to_dense(), b_dense * 1.0 / a_dense)
  21. # ToDo: FIXME in GH 13843
  22. if not (self._base == pd.Series and a.dtype == 'int64'):
  23. self._assert((a // b).to_dense(), a_dense // b_dense)
  24. self._assert((b // a).to_dense(), b_dense // a_dense)
  25. self._assert((a % b).to_dense(), a_dense % b_dense)
  26. self._assert((b % a).to_dense(), b_dense % a_dense)
  27. self._assert((a ** b).to_dense(), a_dense ** b_dense)
  28. self._assert((b ** a).to_dense(), b_dense ** a_dense)
  29. # sparse & dense
  30. self._assert((a + b_dense).to_dense(), a_dense + b_dense)
  31. self._assert((b_dense + a).to_dense(), b_dense + a_dense)
  32. self._assert((a - b_dense).to_dense(), a_dense - b_dense)
  33. self._assert((b_dense - a).to_dense(), b_dense - a_dense)
  34. self._assert((a * b_dense).to_dense(), a_dense * b_dense)
  35. self._assert((b_dense * a).to_dense(), b_dense * a_dense)
  36. # pandas uses future division
  37. self._assert((a / b_dense).to_dense(), a_dense * 1.0 / b_dense)
  38. self._assert((b_dense / a).to_dense(), b_dense * 1.0 / a_dense)
  39. # ToDo: FIXME in GH 13843
  40. if not (self._base == pd.Series and a.dtype == 'int64'):
  41. self._assert((a // b_dense).to_dense(), a_dense // b_dense)
  42. self._assert((b_dense // a).to_dense(), b_dense // a_dense)
  43. self._assert((a % b_dense).to_dense(), a_dense % b_dense)
  44. self._assert((b_dense % a).to_dense(), b_dense % a_dense)
  45. self._assert((a ** b_dense).to_dense(), a_dense ** b_dense)
  46. self._assert((b_dense ** a).to_dense(), b_dense ** a_dense)
  47. def _check_bool_result(self, res):
  48. tm.assertIsInstance(res, self._klass)
  49. self.assertEqual(res.dtype, np.bool)
  50. self.assertIsInstance(res.fill_value, bool)
  51. def _check_comparison_ops(self, a, b, a_dense, b_dense):
  52. # sparse & sparse
  53. self._check_bool_result(a == b)
  54. self._assert((a == b).to_dense(), a_dense == b_dense)
  55. self._check_bool_result(a != b)
  56. self._assert((a != b).to_dense(), a_dense != b_dense)
  57. self._check_bool_result(a >= b)
  58. self._assert((a >= b).to_dense(), a_dense >= b_dense)
  59. self._check_bool_result(a <= b)
  60. self._assert((a <= b).to_dense(), a_dense <= b_dense)
  61. self._check_bool_result(a > b)
  62. self._assert((a > b).to_dense(), a_dense > b_dense)
  63. self._check_bool_result(a < b)
  64. self._assert((a < b).to_dense(), a_dense < b_dense)
  65. # sparse & dense
  66. self._check_bool_result(a == b_dense)
  67. self._assert((a == b_dense).to_dense(), a_dense == b_dense)
  68. self._check_bool_result(a != b_dense)
  69. self._assert((a != b_dense).to_dense(), a_dense != b_dense)
  70. self._check_bool_result(a >= b_dense)
  71. self._assert((a >= b_dense).to_dense(), a_dense >= b_dense)
  72. self._check_bool_result(a <= b_dense)
  73. self._assert((a <= b_dense).to_dense(), a_dense <= b_dense)
  74. self._check_bool_result(a > b_dense)
  75. self._assert((a > b_dense).to_dense(), a_dense > b_dense)
  76. self._check_bool_result(a < b_dense)
  77. self._assert((a < b_dense).to_dense(), a_dense < b_dense)
  78. def test_float_scalar(self):
  79. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  80. for kind in ['integer', 'block']:
  81. a = self._klass(values, kind=kind)
  82. self._check_numeric_ops(a, 1, values, 1)
  83. self._check_numeric_ops(a, 0, values, 0)
  84. self._check_numeric_ops(a, 3, values, 3)
  85. a = self._klass(values, kind=kind, fill_value=0)
  86. self._check_numeric_ops(a, 1, values, 1)
  87. self._check_numeric_ops(a, 0, values, 0)
  88. self._check_numeric_ops(a, 3, values, 3)
  89. a = self._klass(values, kind=kind, fill_value=2)
  90. self._check_numeric_ops(a, 1, values, 1)
  91. self._check_numeric_ops(a, 0, values, 0)
  92. self._check_numeric_ops(a, 3, values, 3)
  93. def test_float_scalar_comparison(self):
  94. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  95. for kind in ['integer', 'block']:
  96. a = self._klass(values, kind=kind)
  97. self._check_comparison_ops(a, 1, values, 1)
  98. self._check_comparison_ops(a, 0, values, 0)
  99. self._check_comparison_ops(a, 3, values, 3)
  100. a = self._klass(values, kind=kind, fill_value=0)
  101. self._check_comparison_ops(a, 1, values, 1)
  102. self._check_comparison_ops(a, 0, values, 0)
  103. self._check_comparison_ops(a, 3, values, 3)
  104. a = self._klass(values, kind=kind, fill_value=2)
  105. self._check_comparison_ops(a, 1, values, 1)
  106. self._check_comparison_ops(a, 0, values, 0)
  107. self._check_comparison_ops(a, 3, values, 3)
  108. def test_float_same_index(self):
  109. # when sp_index are the same
  110. for kind in ['integer', 'block']:
  111. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  112. rvalues = self._base([np.nan, 2, 3, 4, np.nan, 0, 1, 3, 2, np.nan])
  113. a = self._klass(values, kind=kind)
  114. b = self._klass(rvalues, kind=kind)
  115. self._check_numeric_ops(a, b, values, rvalues)
  116. values = self._base([0., 1., 2., 6., 0., 0., 1., 2., 1., 0.])
  117. rvalues = self._base([0., 2., 3., 4., 0., 0., 1., 3., 2., 0.])
  118. a = self._klass(values, kind=kind, fill_value=0)
  119. b = self._klass(rvalues, kind=kind, fill_value=0)
  120. self._check_numeric_ops(a, b, values, rvalues)
  121. def test_float_same_index_comparison(self):
  122. # when sp_index are the same
  123. for kind in ['integer', 'block']:
  124. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  125. rvalues = self._base([np.nan, 2, 3, 4, np.nan, 0, 1, 3, 2, np.nan])
  126. a = self._klass(values, kind=kind)
  127. b = self._klass(rvalues, kind=kind)
  128. self._check_comparison_ops(a, b, values, rvalues)
  129. values = self._base([0., 1., 2., 6., 0., 0., 1., 2., 1., 0.])
  130. rvalues = self._base([0., 2., 3., 4., 0., 0., 1., 3., 2., 0.])
  131. a = self._klass(values, kind=kind, fill_value=0)
  132. b = self._klass(rvalues, kind=kind, fill_value=0)
  133. self._check_comparison_ops(a, b, values, rvalues)
  134. def test_float_array(self):
  135. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  136. rvalues = self._base([2, np.nan, 2, 3, np.nan, 0, 1, 5, 2, np.nan])
  137. for kind in ['integer', 'block']:
  138. a = self._klass(values, kind=kind)
  139. b = self._klass(rvalues, kind=kind)
  140. self._check_numeric_ops(a, b, values, rvalues)
  141. self._check_numeric_ops(a, b * 0, values, rvalues * 0)
  142. a = self._klass(values, kind=kind, fill_value=0)
  143. b = self._klass(rvalues, kind=kind)
  144. self._check_numeric_ops(a, b, values, rvalues)
  145. a = self._klass(values, kind=kind, fill_value=0)
  146. b = self._klass(rvalues, kind=kind, fill_value=0)
  147. self._check_numeric_ops(a, b, values, rvalues)
  148. a = self._klass(values, kind=kind, fill_value=1)
  149. b = self._klass(rvalues, kind=kind, fill_value=2)
  150. self._check_numeric_ops(a, b, values, rvalues)
  151. def test_float_array_different_kind(self):
  152. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  153. rvalues = self._base([2, np.nan, 2, 3, np.nan, 0, 1, 5, 2, np.nan])
  154. a = self._klass(values, kind='integer')
  155. b = self._klass(rvalues, kind='block')
  156. self._check_numeric_ops(a, b, values, rvalues)
  157. self._check_numeric_ops(a, b * 0, values, rvalues * 0)
  158. a = self._klass(values, kind='integer', fill_value=0)
  159. b = self._klass(rvalues, kind='block')
  160. self._check_numeric_ops(a, b, values, rvalues)
  161. a = self._klass(values, kind='integer', fill_value=0)
  162. b = self._klass(rvalues, kind='block', fill_value=0)
  163. self._check_numeric_ops(a, b, values, rvalues)
  164. a = self._klass(values, kind='integer', fill_value=1)
  165. b = self._klass(rvalues, kind='block', fill_value=2)
  166. self._check_numeric_ops(a, b, values, rvalues)
  167. def test_float_array_comparison(self):
  168. values = self._base([np.nan, 1, 2, 0, np.nan, 0, 1, 2, 1, np.nan])
  169. rvalues = self._base([2, np.nan, 2, 3, np.nan, 0, 1, 5, 2, np.nan])
  170. for kind in ['integer', 'block']:
  171. a = self._klass(values, kind=kind)
  172. b = self._klass(rvalues, kind=kind)
  173. self._check_comparison_ops(a, b, values, rvalues)
  174. self._check_comparison_ops(a, b * 0, values, rvalues * 0)
  175. a = self._klass(values, kind=kind, fill_value=0)
  176. b = self._klass(rvalues, kind=kind)
  177. self._check_comparison_ops(a, b, values, rvalues)
  178. a = self._klass(values, kind=kind, fill_value=0)
  179. b = self._klass(rvalues, kind=kind, fill_value=0)
  180. self._check_comparison_ops(a, b, values, rvalues)
  181. a = self._klass(values, kind=kind, fill_value=1)
  182. b = self._klass(rvalues, kind=kind, fill_value=2)
  183. self._check_comparison_ops(a, b, values, rvalues)
  184. def test_int_array(self):
  185. # have to specify dtype explicitly until fixing GH 667
  186. dtype = np.int64
  187. values = self._base([0, 1, 2, 0, 0, 0, 1, 2, 1, 0], dtype=dtype)
  188. rvalues = self._base([2, 0, 2, 3, 0, 0, 1, 5, 2, 0], dtype=dtype)
  189. for kind in ['integer', 'block']:
  190. a = self._klass(values, dtype=dtype, kind=kind)
  191. self.assertEqual(a.dtype, dtype)
  192. b = self._klass(rvalues, dtype=dtype, kind=kind)
  193. self.assertEqual(b.dtype, dtype)
  194. self._check_numeric_ops(a, b, values, rvalues)
  195. self._check_numeric_ops(a, b * 0, values, rvalues * 0)
  196. a = self._klass(values, fill_value=0, dtype=dtype, kind=kind)
  197. self.assertEqual(a.dtype, dtype)
  198. b = self._klass(rvalues, dtype=dtype, kind=kind)
  199. self.assertEqual(b.dtype, dtype)
  200. self._check_numeric_ops(a, b, values, rvalues)
  201. a = self._klass(values, fill_value=0, dtype=dtype, kind=kind)
  202. self.assertEqual(a.dtype, dtype)
  203. b = self._klass(rvalues, fill_value=0, dtype=dtype, kind=kind)
  204. self.assertEqual(b.dtype, dtype)
  205. self._check_numeric_ops(a, b, values, rvalues)
  206. a = self._klass(values, fill_value=1, dtype=dtype, kind=kind)
  207. self.assertEqual(a.dtype, dtype)
  208. b = self._klass(rvalues, fill_value=2, dtype=dtype, kind=kind)
  209. self.assertEqual(b.dtype, dtype)
  210. self._check_numeric_ops(a, b, values, rvalues)
  211. def test_int_array_comparison(self):
  212. # int32 NI ATM
  213. for dtype in ['int64']:
  214. values = self._base([0, 1, 2, 0, 0, 0, 1, 2, 1, 0], dtype=dtype)
  215. rvalues = self._base([2, 0, 2, 3, 0, 0, 1, 5, 2, 0], dtype=dtype)
  216. for kind in ['integer', 'block']:
  217. a = self._klass(values, dtype=dtype, kind=kind)
  218. b = self._klass(rvalues, dtype=dtype, kind=kind)
  219. self._check_comparison_ops(a, b, values, rvalues)
  220. self._check_comparison_ops(a, b * 0, values, rvalues * 0)
  221. a = self._klass(values, dtype=dtype, kind=kind, fill_value=0)
  222. b = self._klass(rvalues, dtype=dtype, kind=kind)
  223. self._check_comparison_ops(a, b, values, rvalues)
  224. a = self._klass(values, dtype=dtype, kind=kind, fill_value=0)
  225. b = self._klass(rvalues, dtype=dtype, kind=kind, fill_value=0)
  226. self._check_comparison_ops(a, b, values, rvalues)
  227. a = self._klass(values, dtype=dtype, kind=kind, fill_value=1)
  228. b = self._klass(rvalues, dtype=dtype, kind=kind, fill_value=2)
  229. self._check_comparison_ops(a, b, values, rvalues)
  230. class TestSparseSeriesArithmetic(TestSparseArrayArithmetics):
  231. _base = pd.Series
  232. _klass = pd.SparseSeries
  233. def _assert(self, a, b):
  234. tm.assert_series_equal(a, b)
  235. def _check_bool_result(self, res):
  236. # ToDo: Must return SparseSeries after GH 667
  237. tm.assertIsInstance(res, self._base)
  238. self.assertEqual(res.dtype, np.bool)
  239. def test_alignment(self):
  240. da = pd.Series(np.arange(4))
  241. db = pd.Series(np.arange(4), index=[1, 2, 3, 4])
  242. sa = pd.SparseSeries(np.arange(4), dtype=np.int64, fill_value=0)
  243. sb = pd.SparseSeries(np.arange(4), index=[1, 2, 3, 4],
  244. dtype=np.int64, fill_value=0)
  245. self._check_numeric_ops(sa, sb, da, db)
  246. sa = pd.SparseSeries(np.arange(4), dtype=np.int64, fill_value=np.nan)
  247. sb = pd.SparseSeries(np.arange(4), index=[1, 2, 3, 4],
  248. dtype=np.int64, fill_value=np.nan)
  249. self._check_numeric_ops(sa, sb, da, db)
  250. da = pd.Series(np.arange(4))
  251. db = pd.Series(np.arange(4), index=[10, 11, 12, 13])
  252. sa = pd.SparseSeries(np.arange(4), dtype=np.int64, fill_value=0)
  253. sb = pd.SparseSeries(np.arange(4), index=[10, 11, 12, 13],
  254. dtype=np.int64, fill_value=0)
  255. self._check_numeric_ops(sa, sb, da, db)
  256. sa = pd.SparseSeries(np.arange(4), dtype=np.int64, fill_value=np.nan)
  257. sb = pd.SparseSeries(np.arange(4), index=[10, 11, 12, 13],
  258. dtype=np.int64, fill_value=np.nan)
  259. self._check_numeric_ops(sa, sb, da, db)