test_arithmetic.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. # -*- coding: utf-8 -*-
  2. from collections import deque
  3. from datetime import datetime
  4. import operator
  5. import numpy as np
  6. import pytest
  7. from pandas.compat import range
  8. import pandas as pd
  9. from pandas.tests.frame.common import _check_mixed_float, _check_mixed_int
  10. import pandas.util.testing as tm
  11. # -------------------------------------------------------------------
  12. # Comparisons
  13. class TestFrameComparisons(object):
  14. # Specifically _not_ flex-comparisons
  15. def test_comparison_invalid(self):
  16. def check(df, df2):
  17. for (x, y) in [(df, df2), (df2, df)]:
  18. # we expect the result to match Series comparisons for
  19. # == and !=, inequalities should raise
  20. result = x == y
  21. expected = pd.DataFrame({col: x[col] == y[col]
  22. for col in x.columns},
  23. index=x.index, columns=x.columns)
  24. tm.assert_frame_equal(result, expected)
  25. result = x != y
  26. expected = pd.DataFrame({col: x[col] != y[col]
  27. for col in x.columns},
  28. index=x.index, columns=x.columns)
  29. tm.assert_frame_equal(result, expected)
  30. with pytest.raises(TypeError):
  31. x >= y
  32. with pytest.raises(TypeError):
  33. x > y
  34. with pytest.raises(TypeError):
  35. x < y
  36. with pytest.raises(TypeError):
  37. x <= y
  38. # GH4968
  39. # invalid date/int comparisons
  40. df = pd.DataFrame(np.random.randint(10, size=(10, 1)), columns=['a'])
  41. df['dates'] = pd.date_range('20010101', periods=len(df))
  42. df2 = df.copy()
  43. df2['dates'] = df['a']
  44. check(df, df2)
  45. df = pd.DataFrame(np.random.randint(10, size=(10, 2)),
  46. columns=['a', 'b'])
  47. df2 = pd.DataFrame({'a': pd.date_range('20010101', periods=len(df)),
  48. 'b': pd.date_range('20100101', periods=len(df))})
  49. check(df, df2)
  50. def test_timestamp_compare(self):
  51. # make sure we can compare Timestamps on the right AND left hand side
  52. # GH#4982
  53. df = pd. DataFrame({'dates1': pd.date_range('20010101', periods=10),
  54. 'dates2': pd.date_range('20010102', periods=10),
  55. 'intcol': np.random.randint(1000000000, size=10),
  56. 'floatcol': np.random.randn(10),
  57. 'stringcol': list(tm.rands(10))})
  58. df.loc[np.random.rand(len(df)) > 0.5, 'dates2'] = pd.NaT
  59. ops = {'gt': 'lt', 'lt': 'gt', 'ge': 'le', 'le': 'ge', 'eq': 'eq',
  60. 'ne': 'ne'}
  61. for left, right in ops.items():
  62. left_f = getattr(operator, left)
  63. right_f = getattr(operator, right)
  64. # no nats
  65. if left in ['eq', 'ne']:
  66. expected = left_f(df, pd.Timestamp('20010109'))
  67. result = right_f(pd.Timestamp('20010109'), df)
  68. tm.assert_frame_equal(result, expected)
  69. else:
  70. with pytest.raises(TypeError):
  71. left_f(df, pd.Timestamp('20010109'))
  72. with pytest.raises(TypeError):
  73. right_f(pd.Timestamp('20010109'), df)
  74. # nats
  75. expected = left_f(df, pd.Timestamp('nat'))
  76. result = right_f(pd.Timestamp('nat'), df)
  77. tm.assert_frame_equal(result, expected)
  78. def test_mixed_comparison(self):
  79. # GH#13128, GH#22163 != datetime64 vs non-dt64 should be False,
  80. # not raise TypeError
  81. # (this appears to be fixed before GH#22163, not sure when)
  82. df = pd.DataFrame([['1989-08-01', 1], ['1989-08-01', 2]])
  83. other = pd.DataFrame([['a', 'b'], ['c', 'd']])
  84. result = df == other
  85. assert not result.any().any()
  86. result = df != other
  87. assert result.all().all()
  88. def test_df_boolean_comparison_error(self):
  89. # GH#4576, GH#22880
  90. # comparing DataFrame against list/tuple with len(obj) matching
  91. # len(df.columns) is supported as of GH#22800
  92. df = pd.DataFrame(np.arange(6).reshape((3, 2)))
  93. expected = pd.DataFrame([[False, False],
  94. [True, False],
  95. [False, False]])
  96. result = df == (2, 2)
  97. tm.assert_frame_equal(result, expected)
  98. result = df == [2, 2]
  99. tm.assert_frame_equal(result, expected)
  100. def test_df_float_none_comparison(self):
  101. df = pd.DataFrame(np.random.randn(8, 3), index=range(8),
  102. columns=['A', 'B', 'C'])
  103. result = df.__eq__(None)
  104. assert not result.any().any()
  105. def test_df_string_comparison(self):
  106. df = pd.DataFrame([{"a": 1, "b": "foo"}, {"a": 2, "b": "bar"}])
  107. mask_a = df.a > 1
  108. tm.assert_frame_equal(df[mask_a], df.loc[1:1, :])
  109. tm.assert_frame_equal(df[-mask_a], df.loc[0:0, :])
  110. mask_b = df.b == "foo"
  111. tm.assert_frame_equal(df[mask_b], df.loc[0:0, :])
  112. tm.assert_frame_equal(df[-mask_b], df.loc[1:1, :])
  113. class TestFrameFlexComparisons(object):
  114. # TODO: test_bool_flex_frame needs a better name
  115. def test_bool_flex_frame(self):
  116. data = np.random.randn(5, 3)
  117. other_data = np.random.randn(5, 3)
  118. df = pd.DataFrame(data)
  119. other = pd.DataFrame(other_data)
  120. ndim_5 = np.ones(df.shape + (1, 3))
  121. # Unaligned
  122. def _check_unaligned_frame(meth, op, df, other):
  123. part_o = other.loc[3:, 1:].copy()
  124. rs = meth(part_o)
  125. xp = op(df, part_o.reindex(index=df.index, columns=df.columns))
  126. tm.assert_frame_equal(rs, xp)
  127. # DataFrame
  128. assert df.eq(df).values.all()
  129. assert not df.ne(df).values.any()
  130. for op in ['eq', 'ne', 'gt', 'lt', 'ge', 'le']:
  131. f = getattr(df, op)
  132. o = getattr(operator, op)
  133. # No NAs
  134. tm.assert_frame_equal(f(other), o(df, other))
  135. _check_unaligned_frame(f, o, df, other)
  136. # ndarray
  137. tm.assert_frame_equal(f(other.values), o(df, other.values))
  138. # scalar
  139. tm.assert_frame_equal(f(0), o(df, 0))
  140. # NAs
  141. msg = "Unable to coerce to Series/DataFrame"
  142. tm.assert_frame_equal(f(np.nan), o(df, np.nan))
  143. with pytest.raises(ValueError, match=msg):
  144. f(ndim_5)
  145. # Series
  146. def _test_seq(df, idx_ser, col_ser):
  147. idx_eq = df.eq(idx_ser, axis=0)
  148. col_eq = df.eq(col_ser)
  149. idx_ne = df.ne(idx_ser, axis=0)
  150. col_ne = df.ne(col_ser)
  151. tm.assert_frame_equal(col_eq, df == pd.Series(col_ser))
  152. tm.assert_frame_equal(col_eq, -col_ne)
  153. tm.assert_frame_equal(idx_eq, -idx_ne)
  154. tm.assert_frame_equal(idx_eq, df.T.eq(idx_ser).T)
  155. tm.assert_frame_equal(col_eq, df.eq(list(col_ser)))
  156. tm.assert_frame_equal(idx_eq, df.eq(pd.Series(idx_ser), axis=0))
  157. tm.assert_frame_equal(idx_eq, df.eq(list(idx_ser), axis=0))
  158. idx_gt = df.gt(idx_ser, axis=0)
  159. col_gt = df.gt(col_ser)
  160. idx_le = df.le(idx_ser, axis=0)
  161. col_le = df.le(col_ser)
  162. tm.assert_frame_equal(col_gt, df > pd.Series(col_ser))
  163. tm.assert_frame_equal(col_gt, -col_le)
  164. tm.assert_frame_equal(idx_gt, -idx_le)
  165. tm.assert_frame_equal(idx_gt, df.T.gt(idx_ser).T)
  166. idx_ge = df.ge(idx_ser, axis=0)
  167. col_ge = df.ge(col_ser)
  168. idx_lt = df.lt(idx_ser, axis=0)
  169. col_lt = df.lt(col_ser)
  170. tm.assert_frame_equal(col_ge, df >= pd.Series(col_ser))
  171. tm.assert_frame_equal(col_ge, -col_lt)
  172. tm.assert_frame_equal(idx_ge, -idx_lt)
  173. tm.assert_frame_equal(idx_ge, df.T.ge(idx_ser).T)
  174. idx_ser = pd.Series(np.random.randn(5))
  175. col_ser = pd.Series(np.random.randn(3))
  176. _test_seq(df, idx_ser, col_ser)
  177. # list/tuple
  178. _test_seq(df, idx_ser.values, col_ser.values)
  179. # NA
  180. df.loc[0, 0] = np.nan
  181. rs = df.eq(df)
  182. assert not rs.loc[0, 0]
  183. rs = df.ne(df)
  184. assert rs.loc[0, 0]
  185. rs = df.gt(df)
  186. assert not rs.loc[0, 0]
  187. rs = df.lt(df)
  188. assert not rs.loc[0, 0]
  189. rs = df.ge(df)
  190. assert not rs.loc[0, 0]
  191. rs = df.le(df)
  192. assert not rs.loc[0, 0]
  193. # complex
  194. arr = np.array([np.nan, 1, 6, np.nan])
  195. arr2 = np.array([2j, np.nan, 7, None])
  196. df = pd.DataFrame({'a': arr})
  197. df2 = pd.DataFrame({'a': arr2})
  198. rs = df.gt(df2)
  199. assert not rs.values.any()
  200. rs = df.ne(df2)
  201. assert rs.values.all()
  202. arr3 = np.array([2j, np.nan, None])
  203. df3 = pd.DataFrame({'a': arr3})
  204. rs = df3.gt(2j)
  205. assert not rs.values.any()
  206. # corner, dtype=object
  207. df1 = pd.DataFrame({'col': ['foo', np.nan, 'bar']})
  208. df2 = pd.DataFrame({'col': ['foo', datetime.now(), 'bar']})
  209. result = df1.ne(df2)
  210. exp = pd.DataFrame({'col': [False, True, False]})
  211. tm.assert_frame_equal(result, exp)
  212. def test_flex_comparison_nat(self):
  213. # GH 15697, GH 22163 df.eq(pd.NaT) should behave like df == pd.NaT,
  214. # and _definitely_ not be NaN
  215. df = pd.DataFrame([pd.NaT])
  216. result = df == pd.NaT
  217. # result.iloc[0, 0] is a np.bool_ object
  218. assert result.iloc[0, 0].item() is False
  219. result = df.eq(pd.NaT)
  220. assert result.iloc[0, 0].item() is False
  221. result = df != pd.NaT
  222. assert result.iloc[0, 0].item() is True
  223. result = df.ne(pd.NaT)
  224. assert result.iloc[0, 0].item() is True
  225. @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le'])
  226. def test_df_flex_cmp_constant_return_types(self, opname):
  227. # GH 15077, non-empty DataFrame
  228. df = pd.DataFrame({'x': [1, 2, 3], 'y': [1., 2., 3.]})
  229. const = 2
  230. result = getattr(df, opname)(const).get_dtype_counts()
  231. tm.assert_series_equal(result, pd.Series([2], ['bool']))
  232. @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le'])
  233. def test_df_flex_cmp_constant_return_types_empty(self, opname):
  234. # GH 15077 empty DataFrame
  235. df = pd.DataFrame({'x': [1, 2, 3], 'y': [1., 2., 3.]})
  236. const = 2
  237. empty = df.iloc[:0]
  238. result = getattr(empty, opname)(const).get_dtype_counts()
  239. tm.assert_series_equal(result, pd.Series([2], ['bool']))
  240. # -------------------------------------------------------------------
  241. # Arithmetic
  242. class TestFrameFlexArithmetic(object):
  243. def test_df_add_td64_columnwise(self):
  244. # GH 22534 Check that column-wise addition broadcasts correctly
  245. dti = pd.date_range('2016-01-01', periods=10)
  246. tdi = pd.timedelta_range('1', periods=10)
  247. tser = pd.Series(tdi)
  248. df = pd.DataFrame({0: dti, 1: tdi})
  249. result = df.add(tser, axis=0)
  250. expected = pd.DataFrame({0: dti + tdi,
  251. 1: tdi + tdi})
  252. tm.assert_frame_equal(result, expected)
  253. def test_df_add_flex_filled_mixed_dtypes(self):
  254. # GH 19611
  255. dti = pd.date_range('2016-01-01', periods=3)
  256. ser = pd.Series(['1 Day', 'NaT', '2 Days'], dtype='timedelta64[ns]')
  257. df = pd.DataFrame({'A': dti, 'B': ser})
  258. other = pd.DataFrame({'A': ser, 'B': ser})
  259. fill = pd.Timedelta(days=1).to_timedelta64()
  260. result = df.add(other, fill_value=fill)
  261. expected = pd.DataFrame(
  262. {'A': pd.Series(['2016-01-02', '2016-01-03', '2016-01-05'],
  263. dtype='datetime64[ns]'),
  264. 'B': ser * 2})
  265. tm.assert_frame_equal(result, expected)
  266. def test_arith_flex_frame(self, all_arithmetic_operators, float_frame,
  267. mixed_float_frame):
  268. # one instance of parametrized fixture
  269. op = all_arithmetic_operators
  270. def f(x, y):
  271. # r-versions not in operator-stdlib; get op without "r" and invert
  272. if op.startswith('__r'):
  273. return getattr(operator, op.replace('__r', '__'))(y, x)
  274. return getattr(operator, op)(x, y)
  275. result = getattr(float_frame, op)(2 * float_frame)
  276. expected = f(float_frame, 2 * float_frame)
  277. tm.assert_frame_equal(result, expected)
  278. # vs mix float
  279. result = getattr(mixed_float_frame, op)(2 * mixed_float_frame)
  280. expected = f(mixed_float_frame, 2 * mixed_float_frame)
  281. tm.assert_frame_equal(result, expected)
  282. _check_mixed_float(result, dtype=dict(C=None))
  283. @pytest.mark.parametrize('op', ['__add__', '__sub__', '__mul__'])
  284. def test_arith_flex_frame_mixed(self, op, int_frame, mixed_int_frame,
  285. mixed_float_frame):
  286. f = getattr(operator, op)
  287. # vs mix int
  288. result = getattr(mixed_int_frame, op)(2 + mixed_int_frame)
  289. expected = f(mixed_int_frame, 2 + mixed_int_frame)
  290. # no overflow in the uint
  291. dtype = None
  292. if op in ['__sub__']:
  293. dtype = dict(B='uint64', C=None)
  294. elif op in ['__add__', '__mul__']:
  295. dtype = dict(C=None)
  296. tm.assert_frame_equal(result, expected)
  297. _check_mixed_int(result, dtype=dtype)
  298. # vs mix float
  299. result = getattr(mixed_float_frame, op)(2 * mixed_float_frame)
  300. expected = f(mixed_float_frame, 2 * mixed_float_frame)
  301. tm.assert_frame_equal(result, expected)
  302. _check_mixed_float(result, dtype=dict(C=None))
  303. # vs plain int
  304. result = getattr(int_frame, op)(2 * int_frame)
  305. expected = f(int_frame, 2 * int_frame)
  306. tm.assert_frame_equal(result, expected)
  307. def test_arith_flex_frame_raise(self, all_arithmetic_operators,
  308. float_frame):
  309. # one instance of parametrized fixture
  310. op = all_arithmetic_operators
  311. # Check that arrays with dim >= 3 raise
  312. for dim in range(3, 6):
  313. arr = np.ones((1,) * dim)
  314. msg = "Unable to coerce to Series/DataFrame"
  315. with pytest.raises(ValueError, match=msg):
  316. getattr(float_frame, op)(arr)
  317. def test_arith_flex_frame_corner(self, float_frame):
  318. const_add = float_frame.add(1)
  319. tm.assert_frame_equal(const_add, float_frame + 1)
  320. # corner cases
  321. result = float_frame.add(float_frame[:0])
  322. tm.assert_frame_equal(result, float_frame * np.nan)
  323. result = float_frame[:0].add(float_frame)
  324. tm.assert_frame_equal(result, float_frame * np.nan)
  325. with pytest.raises(NotImplementedError, match='fill_value'):
  326. float_frame.add(float_frame.iloc[0], fill_value=3)
  327. with pytest.raises(NotImplementedError, match='fill_value'):
  328. float_frame.add(float_frame.iloc[0], axis='index', fill_value=3)
  329. def test_arith_flex_series(self, simple_frame):
  330. df = simple_frame
  331. row = df.xs('a')
  332. col = df['two']
  333. # after arithmetic refactor, add truediv here
  334. ops = ['add', 'sub', 'mul', 'mod']
  335. for op in ops:
  336. f = getattr(df, op)
  337. op = getattr(operator, op)
  338. tm.assert_frame_equal(f(row), op(df, row))
  339. tm.assert_frame_equal(f(col, axis=0), op(df.T, col).T)
  340. # special case for some reason
  341. tm.assert_frame_equal(df.add(row, axis=None), df + row)
  342. # cases which will be refactored after big arithmetic refactor
  343. tm.assert_frame_equal(df.div(row), df / row)
  344. tm.assert_frame_equal(df.div(col, axis=0), (df.T / col).T)
  345. # broadcasting issue in GH 7325
  346. df = pd.DataFrame(np.arange(3 * 2).reshape((3, 2)), dtype='int64')
  347. expected = pd.DataFrame([[np.nan, np.inf], [1.0, 1.5], [1.0, 1.25]])
  348. result = df.div(df[0], axis='index')
  349. tm.assert_frame_equal(result, expected)
  350. df = pd.DataFrame(np.arange(3 * 2).reshape((3, 2)), dtype='float64')
  351. expected = pd.DataFrame([[np.nan, np.inf], [1.0, 1.5], [1.0, 1.25]])
  352. result = df.div(df[0], axis='index')
  353. tm.assert_frame_equal(result, expected)
  354. def test_arith_flex_zero_len_raises(self):
  355. # GH 19522 passing fill_value to frame flex arith methods should
  356. # raise even in the zero-length special cases
  357. ser_len0 = pd.Series([])
  358. df_len0 = pd.DataFrame([], columns=['A', 'B'])
  359. df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B'])
  360. with pytest.raises(NotImplementedError, match='fill_value'):
  361. df.add(ser_len0, fill_value='E')
  362. with pytest.raises(NotImplementedError, match='fill_value'):
  363. df_len0.sub(df['A'], axis=None, fill_value=3)
  364. class TestFrameArithmetic(object):
  365. def test_df_add_2d_array_rowlike_broadcasts(self):
  366. # GH#23000
  367. arr = np.arange(6).reshape(3, 2)
  368. df = pd.DataFrame(arr, columns=[True, False], index=['A', 'B', 'C'])
  369. rowlike = arr[[1], :] # shape --> (1, ncols)
  370. assert rowlike.shape == (1, df.shape[1])
  371. expected = pd.DataFrame([[2, 4],
  372. [4, 6],
  373. [6, 8]],
  374. columns=df.columns, index=df.index,
  375. # specify dtype explicitly to avoid failing
  376. # on 32bit builds
  377. dtype=arr.dtype)
  378. result = df + rowlike
  379. tm.assert_frame_equal(result, expected)
  380. result = rowlike + df
  381. tm.assert_frame_equal(result, expected)
  382. def test_df_add_2d_array_collike_broadcasts(self):
  383. # GH#23000
  384. arr = np.arange(6).reshape(3, 2)
  385. df = pd.DataFrame(arr, columns=[True, False], index=['A', 'B', 'C'])
  386. collike = arr[:, [1]] # shape --> (nrows, 1)
  387. assert collike.shape == (df.shape[0], 1)
  388. expected = pd.DataFrame([[1, 2],
  389. [5, 6],
  390. [9, 10]],
  391. columns=df.columns, index=df.index,
  392. # specify dtype explicitly to avoid failing
  393. # on 32bit builds
  394. dtype=arr.dtype)
  395. result = df + collike
  396. tm.assert_frame_equal(result, expected)
  397. result = collike + df
  398. tm.assert_frame_equal(result, expected)
  399. def test_df_arith_2d_array_rowlike_broadcasts(self,
  400. all_arithmetic_operators):
  401. # GH#23000
  402. opname = all_arithmetic_operators
  403. arr = np.arange(6).reshape(3, 2)
  404. df = pd.DataFrame(arr, columns=[True, False], index=['A', 'B', 'C'])
  405. rowlike = arr[[1], :] # shape --> (1, ncols)
  406. assert rowlike.shape == (1, df.shape[1])
  407. exvals = [getattr(df.loc['A'], opname)(rowlike.squeeze()),
  408. getattr(df.loc['B'], opname)(rowlike.squeeze()),
  409. getattr(df.loc['C'], opname)(rowlike.squeeze())]
  410. expected = pd.DataFrame(exvals, columns=df.columns, index=df.index)
  411. if opname in ['__rmod__', '__rfloordiv__']:
  412. # exvals will have dtypes [f8, i8, i8] so expected will be
  413. # all-f8, but the DataFrame operation will return mixed dtypes
  414. # use exvals[-1].dtype instead of "i8" for compat with 32-bit
  415. # systems/pythons
  416. expected[False] = expected[False].astype(exvals[-1].dtype)
  417. result = getattr(df, opname)(rowlike)
  418. tm.assert_frame_equal(result, expected)
  419. def test_df_arith_2d_array_collike_broadcasts(self,
  420. all_arithmetic_operators):
  421. # GH#23000
  422. opname = all_arithmetic_operators
  423. arr = np.arange(6).reshape(3, 2)
  424. df = pd.DataFrame(arr, columns=[True, False], index=['A', 'B', 'C'])
  425. collike = arr[:, [1]] # shape --> (nrows, 1)
  426. assert collike.shape == (df.shape[0], 1)
  427. exvals = {True: getattr(df[True], opname)(collike.squeeze()),
  428. False: getattr(df[False], opname)(collike.squeeze())}
  429. dtype = None
  430. if opname in ['__rmod__', '__rfloordiv__']:
  431. # Series ops may return mixed int/float dtypes in cases where
  432. # DataFrame op will return all-float. So we upcast `expected`
  433. dtype = np.common_type(*[x.values for x in exvals.values()])
  434. expected = pd.DataFrame(exvals, columns=df.columns, index=df.index,
  435. dtype=dtype)
  436. result = getattr(df, opname)(collike)
  437. tm.assert_frame_equal(result, expected)
  438. def test_df_bool_mul_int(self):
  439. # GH 22047, GH 22163 multiplication by 1 should result in int dtype,
  440. # not object dtype
  441. df = pd.DataFrame([[False, True], [False, False]])
  442. result = df * 1
  443. # On appveyor this comes back as np.int32 instead of np.int64,
  444. # so we check dtype.kind instead of just dtype
  445. kinds = result.dtypes.apply(lambda x: x.kind)
  446. assert (kinds == 'i').all()
  447. result = 1 * df
  448. kinds = result.dtypes.apply(lambda x: x.kind)
  449. assert (kinds == 'i').all()
  450. def test_arith_mixed(self):
  451. left = pd.DataFrame({'A': ['a', 'b', 'c'],
  452. 'B': [1, 2, 3]})
  453. result = left + left
  454. expected = pd.DataFrame({'A': ['aa', 'bb', 'cc'],
  455. 'B': [2, 4, 6]})
  456. tm.assert_frame_equal(result, expected)
  457. def test_arith_getitem_commute(self):
  458. df = pd.DataFrame({'A': [1.1, 3.3], 'B': [2.5, -3.9]})
  459. def _test_op(df, op):
  460. result = op(df, 1)
  461. if not df.columns.is_unique:
  462. raise ValueError("Only unique columns supported by this test")
  463. for col in result.columns:
  464. tm.assert_series_equal(result[col], op(df[col], 1))
  465. _test_op(df, operator.add)
  466. _test_op(df, operator.sub)
  467. _test_op(df, operator.mul)
  468. _test_op(df, operator.truediv)
  469. _test_op(df, operator.floordiv)
  470. _test_op(df, operator.pow)
  471. _test_op(df, lambda x, y: y + x)
  472. _test_op(df, lambda x, y: y - x)
  473. _test_op(df, lambda x, y: y * x)
  474. _test_op(df, lambda x, y: y / x)
  475. _test_op(df, lambda x, y: y ** x)
  476. _test_op(df, lambda x, y: x + y)
  477. _test_op(df, lambda x, y: x - y)
  478. _test_op(df, lambda x, y: x * y)
  479. _test_op(df, lambda x, y: x / y)
  480. _test_op(df, lambda x, y: x ** y)
  481. @pytest.mark.parametrize('values', [[1, 2], (1, 2), np.array([1, 2]),
  482. range(1, 3), deque([1, 2])])
  483. def test_arith_alignment_non_pandas_object(self, values):
  484. # GH#17901
  485. df = pd.DataFrame({'A': [1, 1], 'B': [1, 1]})
  486. expected = pd.DataFrame({'A': [2, 2], 'B': [3, 3]})
  487. result = df + values
  488. tm.assert_frame_equal(result, expected)
  489. def test_arith_non_pandas_object(self):
  490. df = pd.DataFrame(np.arange(1, 10, dtype='f8').reshape(3, 3),
  491. columns=['one', 'two', 'three'],
  492. index=['a', 'b', 'c'])
  493. val1 = df.xs('a').values
  494. added = pd.DataFrame(df.values + val1,
  495. index=df.index, columns=df.columns)
  496. tm.assert_frame_equal(df + val1, added)
  497. added = pd.DataFrame((df.values.T + val1).T,
  498. index=df.index, columns=df.columns)
  499. tm.assert_frame_equal(df.add(val1, axis=0), added)
  500. val2 = list(df['two'])
  501. added = pd.DataFrame(df.values + val2,
  502. index=df.index, columns=df.columns)
  503. tm.assert_frame_equal(df + val2, added)
  504. added = pd.DataFrame((df.values.T + val2).T, index=df.index,
  505. columns=df.columns)
  506. tm.assert_frame_equal(df.add(val2, axis='index'), added)
  507. val3 = np.random.rand(*df.shape)
  508. added = pd.DataFrame(df.values + val3,
  509. index=df.index, columns=df.columns)
  510. tm.assert_frame_equal(df.add(val3), added)