test_operators.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. # coding=utf-8
  2. # pylint: disable-msg=E1101,W0612
  3. from datetime import datetime, timedelta
  4. import operator
  5. import numpy as np
  6. import pytest
  7. import pandas.compat as compat
  8. from pandas.compat import range
  9. import pandas as pd
  10. from pandas import (
  11. Categorical, DataFrame, Index, Series, bdate_range, date_range, isna)
  12. from pandas.core import ops
  13. import pandas.core.nanops as nanops
  14. import pandas.util.testing as tm
  15. from pandas.util.testing import (
  16. assert_almost_equal, assert_frame_equal, assert_series_equal)
  17. from .common import TestData
  18. class TestSeriesLogicalOps(object):
  19. @pytest.mark.parametrize('bool_op', [operator.and_,
  20. operator.or_, operator.xor])
  21. def test_bool_operators_with_nas(self, bool_op):
  22. # boolean &, |, ^ should work with object arrays and propagate NAs
  23. ser = Series(bdate_range('1/1/2000', periods=10), dtype=object)
  24. ser[::2] = np.nan
  25. mask = ser.isna()
  26. filled = ser.fillna(ser[0])
  27. result = bool_op(ser < ser[9], ser > ser[3])
  28. expected = bool_op(filled < filled[9], filled > filled[3])
  29. expected[mask] = False
  30. assert_series_equal(result, expected)
  31. def test_operators_bitwise(self):
  32. # GH#9016: support bitwise op for integer types
  33. index = list('bca')
  34. s_tft = Series([True, False, True], index=index)
  35. s_fff = Series([False, False, False], index=index)
  36. s_tff = Series([True, False, False], index=index)
  37. s_empty = Series([])
  38. # TODO: unused
  39. # s_0101 = Series([0, 1, 0, 1])
  40. s_0123 = Series(range(4), dtype='int64')
  41. s_3333 = Series([3] * 4)
  42. s_4444 = Series([4] * 4)
  43. res = s_tft & s_empty
  44. expected = s_fff
  45. assert_series_equal(res, expected)
  46. res = s_tft | s_empty
  47. expected = s_tft
  48. assert_series_equal(res, expected)
  49. res = s_0123 & s_3333
  50. expected = Series(range(4), dtype='int64')
  51. assert_series_equal(res, expected)
  52. res = s_0123 | s_4444
  53. expected = Series(range(4, 8), dtype='int64')
  54. assert_series_equal(res, expected)
  55. s_a0b1c0 = Series([1], list('b'))
  56. res = s_tft & s_a0b1c0
  57. expected = s_tff.reindex(list('abc'))
  58. assert_series_equal(res, expected)
  59. res = s_tft | s_a0b1c0
  60. expected = s_tft.reindex(list('abc'))
  61. assert_series_equal(res, expected)
  62. n0 = 0
  63. res = s_tft & n0
  64. expected = s_fff
  65. assert_series_equal(res, expected)
  66. res = s_0123 & n0
  67. expected = Series([0] * 4)
  68. assert_series_equal(res, expected)
  69. n1 = 1
  70. res = s_tft & n1
  71. expected = s_tft
  72. assert_series_equal(res, expected)
  73. res = s_0123 & n1
  74. expected = Series([0, 1, 0, 1])
  75. assert_series_equal(res, expected)
  76. s_1111 = Series([1] * 4, dtype='int8')
  77. res = s_0123 & s_1111
  78. expected = Series([0, 1, 0, 1], dtype='int64')
  79. assert_series_equal(res, expected)
  80. res = s_0123.astype(np.int16) | s_1111.astype(np.int32)
  81. expected = Series([1, 1, 3, 3], dtype='int32')
  82. assert_series_equal(res, expected)
  83. with pytest.raises(TypeError):
  84. s_1111 & 'a'
  85. with pytest.raises(TypeError):
  86. s_1111 & ['a', 'b', 'c', 'd']
  87. with pytest.raises(TypeError):
  88. s_0123 & np.NaN
  89. with pytest.raises(TypeError):
  90. s_0123 & 3.14
  91. with pytest.raises(TypeError):
  92. s_0123 & [0.1, 4, 3.14, 2]
  93. # s_0123 will be all false now because of reindexing like s_tft
  94. exp = Series([False] * 7, index=[0, 1, 2, 3, 'a', 'b', 'c'])
  95. assert_series_equal(s_tft & s_0123, exp)
  96. # s_tft will be all false now because of reindexing like s_0123
  97. exp = Series([False] * 7, index=[0, 1, 2, 3, 'a', 'b', 'c'])
  98. assert_series_equal(s_0123 & s_tft, exp)
  99. assert_series_equal(s_0123 & False, Series([False] * 4))
  100. assert_series_equal(s_0123 ^ False, Series([False, True, True, True]))
  101. assert_series_equal(s_0123 & [False], Series([False] * 4))
  102. assert_series_equal(s_0123 & (False), Series([False] * 4))
  103. assert_series_equal(s_0123 & Series([False, np.NaN, False, False]),
  104. Series([False] * 4))
  105. s_ftft = Series([False, True, False, True])
  106. assert_series_equal(s_0123 & Series([0.1, 4, -3.14, 2]), s_ftft)
  107. s_abNd = Series(['a', 'b', np.NaN, 'd'])
  108. res = s_0123 & s_abNd
  109. expected = s_ftft
  110. assert_series_equal(res, expected)
  111. def test_scalar_na_logical_ops_corners(self):
  112. s = Series([2, 3, 4, 5, 6, 7, 8, 9, 10])
  113. with pytest.raises(TypeError):
  114. s & datetime(2005, 1, 1)
  115. s = Series([2, 3, 4, 5, 6, 7, 8, 9, datetime(2005, 1, 1)])
  116. s[::2] = np.nan
  117. expected = Series(True, index=s.index)
  118. expected[::2] = False
  119. result = s & list(s)
  120. assert_series_equal(result, expected)
  121. d = DataFrame({'A': s})
  122. # TODO: Fix this exception - needs to be fixed! (see GH5035)
  123. # (previously this was a TypeError because series returned
  124. # NotImplemented
  125. # this is an alignment issue; these are equivalent
  126. # https://github.com/pandas-dev/pandas/issues/5284
  127. with pytest.raises(TypeError):
  128. d.__and__(s, axis='columns')
  129. with pytest.raises(TypeError):
  130. s & d
  131. # this is wrong as its not a boolean result
  132. # result = d.__and__(s,axis='index')
  133. @pytest.mark.parametrize('op', [
  134. operator.and_,
  135. operator.or_,
  136. operator.xor,
  137. ])
  138. def test_logical_ops_with_index(self, op):
  139. # GH#22092, GH#19792
  140. ser = Series([True, True, False, False])
  141. idx1 = Index([True, False, True, False])
  142. idx2 = Index([1, 0, 1, 0])
  143. expected = Series([op(ser[n], idx1[n]) for n in range(len(ser))])
  144. result = op(ser, idx1)
  145. assert_series_equal(result, expected)
  146. expected = Series([op(ser[n], idx2[n]) for n in range(len(ser))],
  147. dtype=bool)
  148. result = op(ser, idx2)
  149. assert_series_equal(result, expected)
  150. @pytest.mark.parametrize("op, expected", [
  151. (ops.rand_, pd.Index([False, True])),
  152. (ops.ror_, pd.Index([False, True])),
  153. (ops.rxor, pd.Index([])),
  154. ])
  155. def test_reverse_ops_with_index(self, op, expected):
  156. # https://github.com/pandas-dev/pandas/pull/23628
  157. # multi-set Index ops are buggy, so let's avoid duplicates...
  158. ser = Series([True, False])
  159. idx = Index([False, True])
  160. result = op(ser, idx)
  161. tm.assert_index_equal(result, expected)
  162. def test_logical_ops_label_based(self):
  163. # GH#4947
  164. # logical ops should be label based
  165. a = Series([True, False, True], list('bca'))
  166. b = Series([False, True, False], list('abc'))
  167. expected = Series([False, True, False], list('abc'))
  168. result = a & b
  169. assert_series_equal(result, expected)
  170. expected = Series([True, True, False], list('abc'))
  171. result = a | b
  172. assert_series_equal(result, expected)
  173. expected = Series([True, False, False], list('abc'))
  174. result = a ^ b
  175. assert_series_equal(result, expected)
  176. # rhs is bigger
  177. a = Series([True, False, True], list('bca'))
  178. b = Series([False, True, False, True], list('abcd'))
  179. expected = Series([False, True, False, False], list('abcd'))
  180. result = a & b
  181. assert_series_equal(result, expected)
  182. expected = Series([True, True, False, False], list('abcd'))
  183. result = a | b
  184. assert_series_equal(result, expected)
  185. # filling
  186. # vs empty
  187. result = a & Series([])
  188. expected = Series([False, False, False], list('bca'))
  189. assert_series_equal(result, expected)
  190. result = a | Series([])
  191. expected = Series([True, False, True], list('bca'))
  192. assert_series_equal(result, expected)
  193. # vs non-matching
  194. result = a & Series([1], ['z'])
  195. expected = Series([False, False, False, False], list('abcz'))
  196. assert_series_equal(result, expected)
  197. result = a | Series([1], ['z'])
  198. expected = Series([True, True, False, False], list('abcz'))
  199. assert_series_equal(result, expected)
  200. # identity
  201. # we would like s[s|e] == s to hold for any e, whether empty or not
  202. for e in [Series([]), Series([1], ['z']),
  203. Series(np.nan, b.index), Series(np.nan, a.index)]:
  204. result = a[a | e]
  205. assert_series_equal(result, a[a])
  206. for e in [Series(['z'])]:
  207. result = a[a | e]
  208. assert_series_equal(result, a[a])
  209. # vs scalars
  210. index = list('bca')
  211. t = Series([True, False, True])
  212. for v in [True, 1, 2]:
  213. result = Series([True, False, True], index=index) | v
  214. expected = Series([True, True, True], index=index)
  215. assert_series_equal(result, expected)
  216. for v in [np.nan, 'foo']:
  217. with pytest.raises(TypeError):
  218. t | v
  219. for v in [False, 0]:
  220. result = Series([True, False, True], index=index) | v
  221. expected = Series([True, False, True], index=index)
  222. assert_series_equal(result, expected)
  223. for v in [True, 1]:
  224. result = Series([True, False, True], index=index) & v
  225. expected = Series([True, False, True], index=index)
  226. assert_series_equal(result, expected)
  227. for v in [False, 0]:
  228. result = Series([True, False, True], index=index) & v
  229. expected = Series([False, False, False], index=index)
  230. assert_series_equal(result, expected)
  231. for v in [np.nan]:
  232. with pytest.raises(TypeError):
  233. t & v
  234. def test_logical_ops_df_compat(self):
  235. # GH#1134
  236. s1 = pd.Series([True, False, True], index=list('ABC'), name='x')
  237. s2 = pd.Series([True, True, False], index=list('ABD'), name='x')
  238. exp = pd.Series([True, False, False, False],
  239. index=list('ABCD'), name='x')
  240. assert_series_equal(s1 & s2, exp)
  241. assert_series_equal(s2 & s1, exp)
  242. # True | np.nan => True
  243. exp = pd.Series([True, True, True, False],
  244. index=list('ABCD'), name='x')
  245. assert_series_equal(s1 | s2, exp)
  246. # np.nan | True => np.nan, filled with False
  247. exp = pd.Series([True, True, False, False],
  248. index=list('ABCD'), name='x')
  249. assert_series_equal(s2 | s1, exp)
  250. # DataFrame doesn't fill nan with False
  251. exp = pd.DataFrame({'x': [True, False, np.nan, np.nan]},
  252. index=list('ABCD'))
  253. assert_frame_equal(s1.to_frame() & s2.to_frame(), exp)
  254. assert_frame_equal(s2.to_frame() & s1.to_frame(), exp)
  255. exp = pd.DataFrame({'x': [True, True, np.nan, np.nan]},
  256. index=list('ABCD'))
  257. assert_frame_equal(s1.to_frame() | s2.to_frame(), exp)
  258. assert_frame_equal(s2.to_frame() | s1.to_frame(), exp)
  259. # different length
  260. s3 = pd.Series([True, False, True], index=list('ABC'), name='x')
  261. s4 = pd.Series([True, True, True, True], index=list('ABCD'), name='x')
  262. exp = pd.Series([True, False, True, False],
  263. index=list('ABCD'), name='x')
  264. assert_series_equal(s3 & s4, exp)
  265. assert_series_equal(s4 & s3, exp)
  266. # np.nan | True => np.nan, filled with False
  267. exp = pd.Series([True, True, True, False],
  268. index=list('ABCD'), name='x')
  269. assert_series_equal(s3 | s4, exp)
  270. # True | np.nan => True
  271. exp = pd.Series([True, True, True, True],
  272. index=list('ABCD'), name='x')
  273. assert_series_equal(s4 | s3, exp)
  274. exp = pd.DataFrame({'x': [True, False, True, np.nan]},
  275. index=list('ABCD'))
  276. assert_frame_equal(s3.to_frame() & s4.to_frame(), exp)
  277. assert_frame_equal(s4.to_frame() & s3.to_frame(), exp)
  278. exp = pd.DataFrame({'x': [True, True, True, np.nan]},
  279. index=list('ABCD'))
  280. assert_frame_equal(s3.to_frame() | s4.to_frame(), exp)
  281. assert_frame_equal(s4.to_frame() | s3.to_frame(), exp)
  282. class TestSeriesComparisons(object):
  283. def test_comparisons(self):
  284. left = np.random.randn(10)
  285. right = np.random.randn(10)
  286. left[:3] = np.nan
  287. result = nanops.nangt(left, right)
  288. with np.errstate(invalid='ignore'):
  289. expected = (left > right).astype('O')
  290. expected[:3] = np.nan
  291. assert_almost_equal(result, expected)
  292. s = Series(['a', 'b', 'c'])
  293. s2 = Series([False, True, False])
  294. # it works!
  295. exp = Series([False, False, False])
  296. assert_series_equal(s == s2, exp)
  297. assert_series_equal(s2 == s, exp)
  298. def test_categorical_comparisons(self):
  299. # GH 8938
  300. # allow equality comparisons
  301. a = Series(list('abc'), dtype="category")
  302. b = Series(list('abc'), dtype="object")
  303. c = Series(['a', 'b', 'cc'], dtype="object")
  304. d = Series(list('acb'), dtype="object")
  305. e = Categorical(list('abc'))
  306. f = Categorical(list('acb'))
  307. # vs scalar
  308. assert not (a == 'a').all()
  309. assert ((a != 'a') == ~(a == 'a')).all()
  310. assert not ('a' == a).all()
  311. assert (a == 'a')[0]
  312. assert ('a' == a)[0]
  313. assert not ('a' != a)[0]
  314. # vs list-like
  315. assert (a == a).all()
  316. assert not (a != a).all()
  317. assert (a == list(a)).all()
  318. assert (a == b).all()
  319. assert (b == a).all()
  320. assert ((~(a == b)) == (a != b)).all()
  321. assert ((~(b == a)) == (b != a)).all()
  322. assert not (a == c).all()
  323. assert not (c == a).all()
  324. assert not (a == d).all()
  325. assert not (d == a).all()
  326. # vs a cat-like
  327. assert (a == e).all()
  328. assert (e == a).all()
  329. assert not (a == f).all()
  330. assert not (f == a).all()
  331. assert ((~(a == e) == (a != e)).all())
  332. assert ((~(e == a) == (e != a)).all())
  333. assert ((~(a == f) == (a != f)).all())
  334. assert ((~(f == a) == (f != a)).all())
  335. # non-equality is not comparable
  336. with pytest.raises(TypeError):
  337. a < b
  338. with pytest.raises(TypeError):
  339. b < a
  340. with pytest.raises(TypeError):
  341. a > b
  342. with pytest.raises(TypeError):
  343. b > a
  344. def test_comparison_tuples(self):
  345. # GH11339
  346. # comparisons vs tuple
  347. s = Series([(1, 1), (1, 2)])
  348. result = s == (1, 2)
  349. expected = Series([False, True])
  350. assert_series_equal(result, expected)
  351. result = s != (1, 2)
  352. expected = Series([True, False])
  353. assert_series_equal(result, expected)
  354. result = s == (0, 0)
  355. expected = Series([False, False])
  356. assert_series_equal(result, expected)
  357. result = s != (0, 0)
  358. expected = Series([True, True])
  359. assert_series_equal(result, expected)
  360. s = Series([(1, 1), (1, 1)])
  361. result = s == (1, 1)
  362. expected = Series([True, True])
  363. assert_series_equal(result, expected)
  364. result = s != (1, 1)
  365. expected = Series([False, False])
  366. assert_series_equal(result, expected)
  367. s = Series([frozenset([1]), frozenset([1, 2])])
  368. result = s == frozenset([1])
  369. expected = Series([True, False])
  370. assert_series_equal(result, expected)
  371. def test_comparison_operators_with_nas(self):
  372. ser = Series(bdate_range('1/1/2000', periods=10), dtype=object)
  373. ser[::2] = np.nan
  374. # test that comparisons work
  375. ops = ['lt', 'le', 'gt', 'ge', 'eq', 'ne']
  376. for op in ops:
  377. val = ser[5]
  378. f = getattr(operator, op)
  379. result = f(ser, val)
  380. expected = f(ser.dropna(), val).reindex(ser.index)
  381. if op == 'ne':
  382. expected = expected.fillna(True).astype(bool)
  383. else:
  384. expected = expected.fillna(False).astype(bool)
  385. assert_series_equal(result, expected)
  386. # fffffffuuuuuuuuuuuu
  387. # result = f(val, s)
  388. # expected = f(val, s.dropna()).reindex(s.index)
  389. # assert_series_equal(result, expected)
  390. def test_unequal_categorical_comparison_raises_type_error(self):
  391. # unequal comparison should raise for unordered cats
  392. cat = Series(Categorical(list("abc")))
  393. with pytest.raises(TypeError):
  394. cat > "b"
  395. cat = Series(Categorical(list("abc"), ordered=False))
  396. with pytest.raises(TypeError):
  397. cat > "b"
  398. # https://github.com/pandas-dev/pandas/issues/9836#issuecomment-92123057
  399. # and following comparisons with scalars not in categories should raise
  400. # for unequal comps, but not for equal/not equal
  401. cat = Series(Categorical(list("abc"), ordered=True))
  402. with pytest.raises(TypeError):
  403. cat < "d"
  404. with pytest.raises(TypeError):
  405. cat > "d"
  406. with pytest.raises(TypeError):
  407. "d" < cat
  408. with pytest.raises(TypeError):
  409. "d" > cat
  410. tm.assert_series_equal(cat == "d", Series([False, False, False]))
  411. tm.assert_series_equal(cat != "d", Series([True, True, True]))
  412. def test_ne(self):
  413. ts = Series([3, 4, 5, 6, 7], [3, 4, 5, 6, 7], dtype=float)
  414. expected = [True, True, False, True, True]
  415. assert tm.equalContents(ts.index != 5, expected)
  416. assert tm.equalContents(~(ts.index == 5), expected)
  417. def test_comp_ops_df_compat(self):
  418. # GH 1134
  419. s1 = pd.Series([1, 2, 3], index=list('ABC'), name='x')
  420. s2 = pd.Series([2, 2, 2], index=list('ABD'), name='x')
  421. s3 = pd.Series([1, 2, 3], index=list('ABC'), name='x')
  422. s4 = pd.Series([2, 2, 2, 2], index=list('ABCD'), name='x')
  423. for left, right in [(s1, s2), (s2, s1), (s3, s4), (s4, s3)]:
  424. msg = "Can only compare identically-labeled Series objects"
  425. with pytest.raises(ValueError, match=msg):
  426. left == right
  427. with pytest.raises(ValueError, match=msg):
  428. left != right
  429. with pytest.raises(ValueError, match=msg):
  430. left < right
  431. msg = "Can only compare identically-labeled DataFrame objects"
  432. with pytest.raises(ValueError, match=msg):
  433. left.to_frame() == right.to_frame()
  434. with pytest.raises(ValueError, match=msg):
  435. left.to_frame() != right.to_frame()
  436. with pytest.raises(ValueError, match=msg):
  437. left.to_frame() < right.to_frame()
  438. def test_compare_series_interval_keyword(self):
  439. # GH 25338
  440. s = Series(['IntervalA', 'IntervalB', 'IntervalC'])
  441. result = s == 'IntervalA'
  442. expected = Series([True, False, False])
  443. assert_series_equal(result, expected)
  444. class TestSeriesFlexComparisonOps(object):
  445. def test_comparison_flex_alignment(self):
  446. left = Series([1, 3, 2], index=list('abc'))
  447. right = Series([2, 2, 2], index=list('bcd'))
  448. exp = pd.Series([False, False, True, False], index=list('abcd'))
  449. assert_series_equal(left.eq(right), exp)
  450. exp = pd.Series([True, True, False, True], index=list('abcd'))
  451. assert_series_equal(left.ne(right), exp)
  452. exp = pd.Series([False, False, True, False], index=list('abcd'))
  453. assert_series_equal(left.le(right), exp)
  454. exp = pd.Series([False, False, False, False], index=list('abcd'))
  455. assert_series_equal(left.lt(right), exp)
  456. exp = pd.Series([False, True, True, False], index=list('abcd'))
  457. assert_series_equal(left.ge(right), exp)
  458. exp = pd.Series([False, True, False, False], index=list('abcd'))
  459. assert_series_equal(left.gt(right), exp)
  460. def test_comparison_flex_alignment_fill(self):
  461. left = Series([1, 3, 2], index=list('abc'))
  462. right = Series([2, 2, 2], index=list('bcd'))
  463. exp = pd.Series([False, False, True, True], index=list('abcd'))
  464. assert_series_equal(left.eq(right, fill_value=2), exp)
  465. exp = pd.Series([True, True, False, False], index=list('abcd'))
  466. assert_series_equal(left.ne(right, fill_value=2), exp)
  467. exp = pd.Series([False, False, True, True], index=list('abcd'))
  468. assert_series_equal(left.le(right, fill_value=0), exp)
  469. exp = pd.Series([False, False, False, True], index=list('abcd'))
  470. assert_series_equal(left.lt(right, fill_value=0), exp)
  471. exp = pd.Series([True, True, True, False], index=list('abcd'))
  472. assert_series_equal(left.ge(right, fill_value=0), exp)
  473. exp = pd.Series([True, True, False, False], index=list('abcd'))
  474. assert_series_equal(left.gt(right, fill_value=0), exp)
  475. class TestSeriesOperators(TestData):
  476. def test_operators_empty_int_corner(self):
  477. s1 = Series([], [], dtype=np.int32)
  478. s2 = Series({'x': 0.})
  479. assert_series_equal(s1 * s2, Series([np.nan], index=['x']))
  480. def test_ops_datetimelike_align(self):
  481. # GH 7500
  482. # datetimelike ops need to align
  483. dt = Series(date_range('2012-1-1', periods=3, freq='D'))
  484. dt.iloc[2] = np.nan
  485. dt2 = dt[::-1]
  486. expected = Series([timedelta(0), timedelta(0), pd.NaT])
  487. # name is reset
  488. result = dt2 - dt
  489. assert_series_equal(result, expected)
  490. expected = Series(expected, name=0)
  491. result = (dt2.to_frame() - dt.to_frame())[0]
  492. assert_series_equal(result, expected)
  493. def test_operators_corner(self):
  494. series = self.ts
  495. empty = Series([], index=Index([]))
  496. result = series + empty
  497. assert np.isnan(result).all()
  498. result = empty + Series([], index=Index([]))
  499. assert len(result) == 0
  500. # TODO: this returned NotImplemented earlier, what to do?
  501. # deltas = Series([timedelta(1)] * 5, index=np.arange(5))
  502. # sub_deltas = deltas[::2]
  503. # deltas5 = deltas * 5
  504. # deltas = deltas + sub_deltas
  505. # float + int
  506. int_ts = self.ts.astype(int)[:-5]
  507. added = self.ts + int_ts
  508. expected = Series(self.ts.values[:-5] + int_ts.values,
  509. index=self.ts.index[:-5], name='ts')
  510. tm.assert_series_equal(added[:-5], expected)
  511. pairings = []
  512. for op in ['add', 'sub', 'mul', 'pow', 'truediv', 'floordiv']:
  513. fv = 0
  514. lop = getattr(Series, op)
  515. lequiv = getattr(operator, op)
  516. rop = getattr(Series, 'r' + op)
  517. # bind op at definition time...
  518. requiv = lambda x, y, op=op: getattr(operator, op)(y, x)
  519. pairings.append((lop, lequiv, fv))
  520. pairings.append((rop, requiv, fv))
  521. if compat.PY3:
  522. pairings.append((Series.div, operator.truediv, 1))
  523. pairings.append((Series.rdiv, lambda x, y: operator.truediv(y, x), 1))
  524. else:
  525. pairings.append((Series.div, operator.div, 1))
  526. pairings.append((Series.rdiv, lambda x, y: operator.div(y, x), 1))
  527. @pytest.mark.parametrize('op, equiv_op, fv', pairings)
  528. def test_operators_combine(self, op, equiv_op, fv):
  529. def _check_fill(meth, op, a, b, fill_value=0):
  530. exp_index = a.index.union(b.index)
  531. a = a.reindex(exp_index)
  532. b = b.reindex(exp_index)
  533. amask = isna(a)
  534. bmask = isna(b)
  535. exp_values = []
  536. for i in range(len(exp_index)):
  537. with np.errstate(all='ignore'):
  538. if amask[i]:
  539. if bmask[i]:
  540. exp_values.append(np.nan)
  541. continue
  542. exp_values.append(op(fill_value, b[i]))
  543. elif bmask[i]:
  544. if amask[i]:
  545. exp_values.append(np.nan)
  546. continue
  547. exp_values.append(op(a[i], fill_value))
  548. else:
  549. exp_values.append(op(a[i], b[i]))
  550. result = meth(a, b, fill_value=fill_value)
  551. expected = Series(exp_values, exp_index)
  552. assert_series_equal(result, expected)
  553. a = Series([np.nan, 1., 2., 3., np.nan], index=np.arange(5))
  554. b = Series([np.nan, 1, np.nan, 3, np.nan, 4.], index=np.arange(6))
  555. result = op(a, b)
  556. exp = equiv_op(a, b)
  557. assert_series_equal(result, exp)
  558. _check_fill(op, equiv_op, a, b, fill_value=fv)
  559. # should accept axis=0 or axis='rows'
  560. op(a, b, axis=0)
  561. def test_operators_na_handling(self):
  562. from decimal import Decimal
  563. from datetime import date
  564. s = Series([Decimal('1.3'), Decimal('2.3')],
  565. index=[date(2012, 1, 1), date(2012, 1, 2)])
  566. result = s + s.shift(1)
  567. result2 = s.shift(1) + s
  568. assert isna(result[0])
  569. assert isna(result2[0])
  570. def test_op_duplicate_index(self):
  571. # GH14227
  572. s1 = Series([1, 2], index=[1, 1])
  573. s2 = Series([10, 10], index=[1, 2])
  574. result = s1 + s2
  575. expected = pd.Series([11, 12, np.nan], index=[1, 1, 2])
  576. assert_series_equal(result, expected)
  577. class TestSeriesUnaryOps(object):
  578. # __neg__, __pos__, __inv__
  579. def test_neg(self):
  580. ser = tm.makeStringSeries()
  581. ser.name = 'series'
  582. assert_series_equal(-ser, -1 * ser)
  583. def test_invert(self):
  584. ser = tm.makeStringSeries()
  585. ser.name = 'series'
  586. assert_series_equal(-(ser < 0), ~(ser < 0))