PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/pandas/tests/test_base.py

https://github.com/ajcr/pandas
Python | 659 lines | 487 code | 129 blank | 43 comment | 94 complexity | c7ee060af53e85247d1300d67f2eb77c MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. import re
  2. from datetime import datetime, timedelta
  3. import numpy as np
  4. import pandas.compat as compat
  5. import pandas as pd
  6. from pandas.compat import u, StringIO
  7. from pandas.core.base import FrozenList, FrozenNDArray, DatetimeIndexOpsMixin
  8. from pandas.util.testing import assertRaisesRegexp, assert_isinstance
  9. from pandas import Series, Index, Int64Index, DatetimeIndex, PeriodIndex
  10. from pandas import _np_version_under1p7
  11. import pandas.tslib as tslib
  12. import nose
  13. import pandas.util.testing as tm
  14. class CheckStringMixin(object):
  15. def test_string_methods_dont_fail(self):
  16. repr(self.container)
  17. str(self.container)
  18. bytes(self.container)
  19. if not compat.PY3:
  20. unicode(self.container)
  21. def test_tricky_container(self):
  22. if not hasattr(self, 'unicode_container'):
  23. raise nose.SkipTest('Need unicode_container to test with this')
  24. repr(self.unicode_container)
  25. str(self.unicode_container)
  26. bytes(self.unicode_container)
  27. if not compat.PY3:
  28. unicode(self.unicode_container)
  29. class CheckImmutable(object):
  30. mutable_regex = re.compile('does not support mutable operations')
  31. def check_mutable_error(self, *args, **kwargs):
  32. # pass whatever functions you normally would to assertRaises (after the Exception kind)
  33. assertRaisesRegexp(TypeError, self.mutable_regex, *args, **kwargs)
  34. def test_no_mutable_funcs(self):
  35. def setitem(): self.container[0] = 5
  36. self.check_mutable_error(setitem)
  37. def setslice(): self.container[1:2] = 3
  38. self.check_mutable_error(setslice)
  39. def delitem(): del self.container[0]
  40. self.check_mutable_error(delitem)
  41. def delslice(): del self.container[0:3]
  42. self.check_mutable_error(delslice)
  43. mutable_methods = getattr(self, "mutable_methods", [])
  44. for meth in mutable_methods:
  45. self.check_mutable_error(getattr(self.container, meth))
  46. def test_slicing_maintains_type(self):
  47. result = self.container[1:2]
  48. expected = self.lst[1:2]
  49. self.check_result(result, expected)
  50. def check_result(self, result, expected, klass=None):
  51. klass = klass or self.klass
  52. assert_isinstance(result, klass)
  53. self.assertEqual(result, expected)
  54. class TestFrozenList(CheckImmutable, CheckStringMixin, tm.TestCase):
  55. mutable_methods = ('extend', 'pop', 'remove', 'insert')
  56. unicode_container = FrozenList([u("\u05d0"), u("\u05d1"), "c"])
  57. def setUp(self):
  58. self.lst = [1, 2, 3, 4, 5]
  59. self.container = FrozenList(self.lst)
  60. self.klass = FrozenList
  61. def test_add(self):
  62. result = self.container + (1, 2, 3)
  63. expected = FrozenList(self.lst + [1, 2, 3])
  64. self.check_result(result, expected)
  65. result = (1, 2, 3) + self.container
  66. expected = FrozenList([1, 2, 3] + self.lst)
  67. self.check_result(result, expected)
  68. def test_inplace(self):
  69. q = r = self.container
  70. q += [5]
  71. self.check_result(q, self.lst + [5])
  72. # other shouldn't be mutated
  73. self.check_result(r, self.lst)
  74. class TestFrozenNDArray(CheckImmutable, CheckStringMixin, tm.TestCase):
  75. mutable_methods = ('put', 'itemset', 'fill')
  76. unicode_container = FrozenNDArray([u("\u05d0"), u("\u05d1"), "c"])
  77. def setUp(self):
  78. self.lst = [3, 5, 7, -2]
  79. self.container = FrozenNDArray(self.lst)
  80. self.klass = FrozenNDArray
  81. def test_shallow_copying(self):
  82. original = self.container.copy()
  83. assert_isinstance(self.container.view(), FrozenNDArray)
  84. self.assertFalse(isinstance(self.container.view(np.ndarray), FrozenNDArray))
  85. self.assertIsNot(self.container.view(), self.container)
  86. self.assert_numpy_array_equal(self.container, original)
  87. # shallow copy should be the same too
  88. assert_isinstance(self.container._shallow_copy(), FrozenNDArray)
  89. # setting should not be allowed
  90. def testit(container): container[0] = 16
  91. self.check_mutable_error(testit, self.container)
  92. def test_values(self):
  93. original = self.container.view(np.ndarray).copy()
  94. n = original[0] + 15
  95. vals = self.container.values()
  96. self.assert_numpy_array_equal(original, vals)
  97. self.assertIsNot(original, vals)
  98. vals[0] = n
  99. self.assert_numpy_array_equal(self.container, original)
  100. self.assertEqual(vals[0], n)
  101. class Ops(tm.TestCase):
  102. def setUp(self):
  103. self.int_index = tm.makeIntIndex(10)
  104. self.float_index = tm.makeFloatIndex(10)
  105. self.dt_index = tm.makeDateIndex(10)
  106. self.dt_tz_index = tm.makeDateIndex(10).tz_localize(tz='US/Eastern')
  107. self.period_index = tm.makePeriodIndex(10)
  108. self.string_index = tm.makeStringIndex(10)
  109. arr = np.random.randn(10)
  110. self.int_series = Series(arr, index=self.int_index)
  111. self.float_series = Series(arr, index=self.int_index)
  112. self.dt_series = Series(arr, index=self.dt_index)
  113. self.dt_tz_series = self.dt_tz_index.to_series(keep_tz=True)
  114. self.period_series = Series(arr, index=self.period_index)
  115. self.string_series = Series(arr, index=self.string_index)
  116. types = ['int','float','dt', 'dt_tz', 'period','string']
  117. self.objs = [ getattr(self,"{0}_{1}".format(t,f)) for t in types for f in ['index','series'] ]
  118. def check_ops_properties(self, props, filter=None, ignore_failures=False):
  119. for op in props:
  120. for o in self.is_valid_objs:
  121. # if a filter, skip if it doesn't match
  122. if filter is not None:
  123. filt = o.index if isinstance(o, Series) else o
  124. if not filter(filt):
  125. continue
  126. try:
  127. if isinstance(o, Series):
  128. expected = Series(getattr(o.index,op),index=o.index)
  129. else:
  130. expected = getattr(o,op)
  131. except (AttributeError):
  132. if ignore_failures:
  133. continue
  134. result = getattr(o,op)
  135. # these couuld be series, arrays or scalars
  136. if isinstance(result,Series) and isinstance(expected,Series):
  137. tm.assert_series_equal(result,expected)
  138. elif isinstance(result,Index) and isinstance(expected,Index):
  139. tm.assert_index_equal(result,expected)
  140. elif isinstance(result,np.ndarray) and isinstance(expected,np.ndarray):
  141. self.assert_numpy_array_equal(result,expected)
  142. else:
  143. self.assertEqual(result, expected)
  144. # freq raises AttributeError on an Int64Index because its not defined
  145. # we mostly care about Series hwere anyhow
  146. if not ignore_failures:
  147. for o in self.not_valid_objs:
  148. # an object that is datetimelike will raise a TypeError, otherwise
  149. # an AttributeError
  150. if issubclass(type(o), DatetimeIndexOpsMixin):
  151. self.assertRaises(TypeError, lambda : getattr(o,op))
  152. else:
  153. self.assertRaises(AttributeError, lambda : getattr(o,op))
  154. class TestIndexOps(Ops):
  155. def setUp(self):
  156. super(TestIndexOps, self).setUp()
  157. self.is_valid_objs = [ o for o in self.objs if o._allow_index_ops ]
  158. self.not_valid_objs = [ o for o in self.objs if not o._allow_index_ops ]
  159. def test_ops(self):
  160. if _np_version_under1p7:
  161. raise nose.SkipTest("test only valid in numpy >= 1.7")
  162. for op in ['max','min']:
  163. for o in self.objs:
  164. result = getattr(o,op)()
  165. if not isinstance(o, PeriodIndex):
  166. expected = getattr(o.values, op)()
  167. else:
  168. expected = pd.Period(ordinal=getattr(o.values, op)(), freq=o.freq)
  169. try:
  170. self.assertEqual(result, expected)
  171. except ValueError:
  172. # comparing tz-aware series with np.array results in ValueError
  173. expected = expected.astype('M8[ns]').astype('int64')
  174. self.assertEqual(result.value, expected)
  175. def test_nanops(self):
  176. # GH 7261
  177. for op in ['max','min']:
  178. for klass in [Index, Series]:
  179. obj = klass([np.nan, 2.0])
  180. self.assertEqual(getattr(obj, op)(), 2.0)
  181. obj = klass([np.nan])
  182. self.assertTrue(pd.isnull(getattr(obj, op)()))
  183. obj = klass([])
  184. self.assertTrue(pd.isnull(getattr(obj, op)()))
  185. obj = klass([pd.NaT, datetime(2011, 11, 1)])
  186. # check DatetimeIndex monotonic path
  187. self.assertEqual(getattr(obj, op)(), datetime(2011, 11, 1))
  188. obj = klass([pd.NaT, datetime(2011, 11, 1), pd.NaT])
  189. # check DatetimeIndex non-monotonic path
  190. self.assertEqual(getattr(obj, op)(), datetime(2011, 11, 1))
  191. def test_value_counts_unique_nunique(self):
  192. for o in self.objs:
  193. klass = type(o)
  194. values = o.values
  195. # create repeated values, 'n'th element is repeated by n+1 times
  196. if isinstance(o, PeriodIndex):
  197. # freq must be specified because repeat makes freq ambiguous
  198. o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq)
  199. else:
  200. o = klass(np.repeat(values, range(1, len(o) + 1)))
  201. expected_s = Series(range(10, 0, -1), index=values[::-1], dtype='int64')
  202. tm.assert_series_equal(o.value_counts(), expected_s)
  203. if isinstance(o, DatetimeIndex):
  204. # DatetimeIndex.unique returns DatetimeIndex
  205. self.assertTrue(o.unique().equals(klass(values)))
  206. else:
  207. self.assert_numpy_array_equal(o.unique(), values)
  208. self.assertEqual(o.nunique(), len(np.unique(o.values)))
  209. for null_obj in [np.nan, None]:
  210. for o in self.objs:
  211. klass = type(o)
  212. values = o.values
  213. if o.values.dtype == 'int64':
  214. # skips int64 because it doesn't allow to include nan or None
  215. continue
  216. if o.values.dtype == 'datetime64[ns]' and _np_version_under1p7:
  217. # Unable to assign None
  218. continue
  219. # special assign to the numpy array
  220. if o.values.dtype == 'datetime64[ns]':
  221. values[0:2] = pd.tslib.iNaT
  222. else:
  223. values[0:2] = null_obj
  224. # create repeated values, 'n'th element is repeated by n+1 times
  225. if isinstance(o, PeriodIndex):
  226. o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq)
  227. else:
  228. o = klass(np.repeat(values, range(1, len(o) + 1)))
  229. if isinstance(o, DatetimeIndex):
  230. expected_s_na = Series(list(range(10, 2, -1)) + [3], index=values[9:0:-1])
  231. expected_s = Series(list(range(10, 2, -1)), index=values[9:1:-1])
  232. else:
  233. expected_s_na = Series(list(range(10, 2, -1)) +[3], index=values[9:0:-1], dtype='int64')
  234. expected_s = Series(list(range(10, 2, -1)), index=values[9:1:-1], dtype='int64')
  235. tm.assert_series_equal(o.value_counts(dropna=False), expected_s_na)
  236. tm.assert_series_equal(o.value_counts(), expected_s)
  237. # numpy_array_equal cannot compare arrays includes nan
  238. result = o.unique()
  239. self.assert_numpy_array_equal(result[1:], values[2:])
  240. if isinstance(o, DatetimeIndex):
  241. self.assertTrue(result[0] is pd.NaT)
  242. else:
  243. self.assertTrue(pd.isnull(result[0]))
  244. self.assertEqual(o.nunique(), 8)
  245. self.assertEqual(o.nunique(dropna=False), 9)
  246. def test_value_counts_inferred(self):
  247. klasses = [Index, Series]
  248. for klass in klasses:
  249. s_values = ['a', 'b', 'b', 'b', 'b', 'c', 'd', 'd', 'a', 'a']
  250. s = klass(s_values)
  251. expected = Series([4, 3, 2, 1], index=['b', 'a', 'd', 'c'])
  252. tm.assert_series_equal(s.value_counts(), expected)
  253. self.assert_numpy_array_equal(s.unique(), np.unique(s_values))
  254. self.assertEqual(s.nunique(), 4)
  255. # don't sort, have to sort after the fact as not sorting is platform-dep
  256. hist = s.value_counts(sort=False)
  257. hist.sort()
  258. expected = Series([3, 1, 4, 2], index=list('acbd'))
  259. expected.sort()
  260. tm.assert_series_equal(hist, expected)
  261. # sort ascending
  262. hist = s.value_counts(ascending=True)
  263. expected = Series([1, 2, 3, 4], index=list('cdab'))
  264. tm.assert_series_equal(hist, expected)
  265. # relative histogram.
  266. hist = s.value_counts(normalize=True)
  267. expected = Series([.4, .3, .2, .1], index=['b', 'a', 'd', 'c'])
  268. tm.assert_series_equal(hist, expected)
  269. # bins
  270. self.assertRaises(TypeError, lambda bins: s.value_counts(bins=bins), 1)
  271. s1 = Series([1, 1, 2, 3])
  272. res1 = s1.value_counts(bins=1)
  273. exp1 = Series({0.998: 4})
  274. tm.assert_series_equal(res1, exp1)
  275. res1n = s1.value_counts(bins=1, normalize=True)
  276. exp1n = Series({0.998: 1.0})
  277. tm.assert_series_equal(res1n, exp1n)
  278. self.assert_numpy_array_equal(s1.unique(), np.array([1, 2, 3]))
  279. self.assertEqual(s1.nunique(), 3)
  280. res4 = s1.value_counts(bins=4)
  281. exp4 = Series({0.998: 2, 1.5: 1, 2.0: 0, 2.5: 1}, index=[0.998, 2.5, 1.5, 2.0])
  282. tm.assert_series_equal(res4, exp4)
  283. res4n = s1.value_counts(bins=4, normalize=True)
  284. exp4n = Series({0.998: 0.5, 1.5: 0.25, 2.0: 0.0, 2.5: 0.25}, index=[0.998, 2.5, 1.5, 2.0])
  285. tm.assert_series_equal(res4n, exp4n)
  286. # handle NA's properly
  287. s_values = ['a', 'b', 'b', 'b', np.nan, np.nan, 'd', 'd', 'a', 'a', 'b']
  288. s = klass(s_values)
  289. expected = Series([4, 3, 2], index=['b', 'a', 'd'])
  290. tm.assert_series_equal(s.value_counts(), expected)
  291. self.assert_numpy_array_equal(s.unique(), np.array(['a', 'b', np.nan, 'd'], dtype='O'))
  292. self.assertEqual(s.nunique(), 3)
  293. s = klass({})
  294. expected = Series([], dtype=np.int64)
  295. tm.assert_series_equal(s.value_counts(), expected)
  296. self.assert_numpy_array_equal(s.unique(), np.array([]))
  297. self.assertEqual(s.nunique(), 0)
  298. # GH 3002, datetime64[ns]
  299. txt = "\n".join(['xxyyzz20100101PIE', 'xxyyzz20100101GUM', 'xxyyzz20100101EGG',
  300. 'xxyyww20090101EGG', 'foofoo20080909PIE', 'foofoo20080909GUM'])
  301. f = StringIO(txt)
  302. df = pd.read_fwf(f, widths=[6, 8, 3], names=["person_id", "dt", "food"],
  303. parse_dates=["dt"])
  304. s = klass(df['dt'].copy())
  305. idx = pd.to_datetime(['2010-01-01 00:00:00Z', '2008-09-09 00:00:00Z', '2009-01-01 00:00:00X'])
  306. expected_s = Series([3, 2, 1], index=idx)
  307. tm.assert_series_equal(s.value_counts(), expected_s)
  308. expected = np.array(['2010-01-01 00:00:00Z', '2009-01-01 00:00:00Z', '2008-09-09 00:00:00Z'],
  309. dtype='datetime64[ns]')
  310. if isinstance(s, DatetimeIndex):
  311. expected = DatetimeIndex(expected)
  312. self.assertTrue(s.unique().equals(expected))
  313. else:
  314. self.assert_numpy_array_equal(s.unique(), expected)
  315. self.assertEqual(s.nunique(), 3)
  316. # with NaT
  317. s = df['dt'].copy()
  318. s = klass([v for v in s.values] + [pd.NaT])
  319. result = s.value_counts()
  320. self.assertEqual(result.index.dtype, 'datetime64[ns]')
  321. tm.assert_series_equal(result, expected_s)
  322. result = s.value_counts(dropna=False)
  323. expected_s[pd.NaT] = 1
  324. tm.assert_series_equal(result, expected_s)
  325. unique = s.unique()
  326. self.assertEqual(unique.dtype, 'datetime64[ns]')
  327. # numpy_array_equal cannot compare pd.NaT
  328. self.assert_numpy_array_equal(unique[:3], expected)
  329. self.assertTrue(unique[3] is pd.NaT or unique[3].astype('int64') == pd.tslib.iNaT)
  330. self.assertEqual(s.nunique(), 3)
  331. self.assertEqual(s.nunique(dropna=False), 4)
  332. # timedelta64[ns]
  333. td = df.dt - df.dt + timedelta(1)
  334. td = klass(td)
  335. result = td.value_counts()
  336. expected_s = Series([6], index=[86400000000000])
  337. self.assertEqual(result.index.dtype, 'int64')
  338. tm.assert_series_equal(result, expected_s)
  339. # get nanoseconds to compare
  340. expected = np.array([86400000000000])
  341. self.assert_numpy_array_equal(td.unique(), expected)
  342. self.assertEqual(td.nunique(), 1)
  343. td2 = timedelta(1) + (df.dt - df.dt)
  344. td2 = klass(td2)
  345. result2 = td2.value_counts()
  346. self.assertEqual(result2.index.dtype, 'int64')
  347. tm.assert_series_equal(result2, expected_s)
  348. self.assert_numpy_array_equal(td.unique(), expected)
  349. self.assertEqual(td.nunique(), 1)
  350. def test_factorize(self):
  351. for o in self.objs:
  352. exp_arr = np.array(range(len(o)))
  353. labels, uniques = o.factorize()
  354. self.assert_numpy_array_equal(labels, exp_arr)
  355. if isinstance(o, Series):
  356. expected = Index(o.values)
  357. self.assert_numpy_array_equal(uniques, expected)
  358. else:
  359. self.assertTrue(uniques.equals(o))
  360. for o in self.objs:
  361. # sort by value, and create duplicates
  362. if isinstance(o, Series):
  363. o.sort()
  364. else:
  365. indexer = o.argsort()
  366. o = o.take(indexer)
  367. n = o[5:].append(o)
  368. exp_arr = np.array([5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  369. labels, uniques = n.factorize(sort=True)
  370. self.assert_numpy_array_equal(labels, exp_arr)
  371. if isinstance(o, Series):
  372. expected = Index(o.values)
  373. self.assert_numpy_array_equal(uniques, expected)
  374. else:
  375. self.assertTrue(uniques.equals(o))
  376. exp_arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4])
  377. labels, uniques = n.factorize(sort=False)
  378. self.assert_numpy_array_equal(labels, exp_arr)
  379. if isinstance(o, Series):
  380. expected = Index(np.concatenate([o.values[5:10], o.values[:5]]))
  381. self.assert_numpy_array_equal(uniques, expected)
  382. else:
  383. expected = o[5:].append(o[:5])
  384. self.assertTrue(uniques.equals(expected))
  385. class TestDatetimeIndexOps(Ops):
  386. _allowed = '_allow_datetime_index_ops'
  387. def setUp(self):
  388. super(TestDatetimeIndexOps, self).setUp()
  389. mask = lambda x: x._allow_datetime_index_ops or x._allow_period_index_ops
  390. self.is_valid_objs = [ o for o in self.objs if mask(o) ]
  391. self.not_valid_objs = [ o for o in self.objs if not mask(o) ]
  392. def test_ops_properties(self):
  393. self.check_ops_properties(['year','month','day','hour','minute','second','weekofyear','week','dayofweek','dayofyear','quarter'])
  394. self.check_ops_properties(['date','time','microsecond','nanosecond', 'is_month_start', 'is_month_end', 'is_quarter_start',
  395. 'is_quarter_end', 'is_year_start', 'is_year_end'], lambda x: isinstance(x,DatetimeIndex))
  396. def test_ops_properties_basic(self):
  397. # sanity check that the behavior didn't change
  398. # GH7206
  399. for op in ['year','day','second','weekday']:
  400. self.assertRaises(TypeError, lambda x: getattr(self.dt_series,op))
  401. # attribute access should still work!
  402. s = Series(dict(year=2000,month=1,day=10))
  403. self.assertEquals(s.year,2000)
  404. self.assertEquals(s.month,1)
  405. self.assertEquals(s.day,10)
  406. self.assertRaises(AttributeError, lambda : s.weekday)
  407. def test_asobject_tolist(self):
  408. idx = pd.date_range(start='2013-01-01', periods=4, freq='M', name='idx')
  409. expected_list = [pd.Timestamp('2013-01-31'), pd.Timestamp('2013-02-28'),
  410. pd.Timestamp('2013-03-31'), pd.Timestamp('2013-04-30')]
  411. expected = pd.Index(expected_list, dtype=object, name='idx')
  412. result = idx.asobject
  413. self.assertTrue(isinstance(result, Index))
  414. self.assertEqual(result.dtype, object)
  415. self.assertTrue(result.equals(expected))
  416. self.assertEqual(result.name, expected.name)
  417. self.assertEqual(idx.tolist(), expected_list)
  418. idx = pd.date_range(start='2013-01-01', periods=4, freq='M', name='idx', tz='Asia/Tokyo')
  419. expected_list = [pd.Timestamp('2013-01-31', tz='Asia/Tokyo'),
  420. pd.Timestamp('2013-02-28', tz='Asia/Tokyo'),
  421. pd.Timestamp('2013-03-31', tz='Asia/Tokyo'),
  422. pd.Timestamp('2013-04-30', tz='Asia/Tokyo')]
  423. expected = pd.Index(expected_list, dtype=object, name='idx')
  424. result = idx.asobject
  425. self.assertTrue(isinstance(result, Index))
  426. self.assertEqual(result.dtype, object)
  427. self.assertTrue(result.equals(expected))
  428. self.assertEqual(result.name, expected.name)
  429. self.assertEqual(idx.tolist(), expected_list)
  430. idx = DatetimeIndex([datetime(2013, 1, 1), datetime(2013, 1, 2),
  431. pd.NaT, datetime(2013, 1, 4)], name='idx')
  432. expected_list = [pd.Timestamp('2013-01-01'), pd.Timestamp('2013-01-02'),
  433. pd.NaT, pd.Timestamp('2013-01-04')]
  434. expected = pd.Index(expected_list, dtype=object, name='idx')
  435. result = idx.asobject
  436. self.assertTrue(isinstance(result, Index))
  437. self.assertEqual(result.dtype, object)
  438. self.assertTrue(result.equals(expected))
  439. self.assertEqual(result.name, expected.name)
  440. self.assertEqual(idx.tolist(), expected_list)
  441. def test_minmax(self):
  442. for tz in [None, 'Asia/Tokyo', 'US/Eastern']:
  443. # monotonic
  444. idx1 = pd.DatetimeIndex([pd.NaT, '2011-01-01', '2011-01-02',
  445. '2011-01-03'], tz=tz)
  446. self.assertTrue(idx1.is_monotonic)
  447. # non-monotonic
  448. idx2 = pd.DatetimeIndex(['2011-01-01', pd.NaT, '2011-01-03',
  449. '2011-01-02', pd.NaT], tz=tz)
  450. self.assertFalse(idx2.is_monotonic)
  451. for idx in [idx1, idx2]:
  452. self.assertEqual(idx.min(), pd.Timestamp('2011-01-01', tz=tz))
  453. self.assertEqual(idx.max(), pd.Timestamp('2011-01-03', tz=tz))
  454. for op in ['min', 'max']:
  455. # Return NaT
  456. obj = DatetimeIndex([])
  457. self.assertTrue(pd.isnull(getattr(obj, op)()))
  458. obj = DatetimeIndex([pd.NaT])
  459. self.assertTrue(pd.isnull(getattr(obj, op)()))
  460. obj = DatetimeIndex([pd.NaT, pd.NaT, pd.NaT])
  461. self.assertTrue(pd.isnull(getattr(obj, op)()))
  462. class TestPeriodIndexOps(Ops):
  463. _allowed = '_allow_period_index_ops'
  464. def setUp(self):
  465. super(TestPeriodIndexOps, self).setUp()
  466. mask = lambda x: x._allow_datetime_index_ops or x._allow_period_index_ops
  467. self.is_valid_objs = [ o for o in self.objs if mask(o) ]
  468. self.not_valid_objs = [ o for o in self.objs if not mask(o) ]
  469. def test_ops_properties(self):
  470. self.check_ops_properties(['year','month','day','hour','minute','second','weekofyear','week','dayofweek','dayofyear','quarter'])
  471. self.check_ops_properties(['qyear'], lambda x: isinstance(x,PeriodIndex))
  472. def test_asobject_tolist(self):
  473. idx = pd.period_range(start='2013-01-01', periods=4, freq='M', name='idx')
  474. expected_list = [pd.Period('2013-01-31', freq='M'), pd.Period('2013-02-28', freq='M'),
  475. pd.Period('2013-03-31', freq='M'), pd.Period('2013-04-30', freq='M')]
  476. expected = pd.Index(expected_list, dtype=object, name='idx')
  477. result = idx.asobject
  478. self.assertTrue(isinstance(result, Index))
  479. self.assertEqual(result.dtype, object)
  480. self.assertTrue(result.equals(expected))
  481. self.assertEqual(result.name, expected.name)
  482. self.assertEqual(idx.tolist(), expected_list)
  483. idx = PeriodIndex(['2013-01-01', '2013-01-02', 'NaT', '2013-01-04'], freq='D', name='idx')
  484. expected_list = [pd.Period('2013-01-01', freq='D'), pd.Period('2013-01-02', freq='D'),
  485. pd.Period('NaT', freq='D'), pd.Period('2013-01-04', freq='D')]
  486. expected = pd.Index(expected_list, dtype=object, name='idx')
  487. result = idx.asobject
  488. self.assertTrue(isinstance(result, Index))
  489. self.assertEqual(result.dtype, object)
  490. for i in [0, 1, 3]:
  491. self.assertTrue(result[i], expected[i])
  492. self.assertTrue(result[2].ordinal, pd.tslib.iNaT)
  493. self.assertTrue(result[2].freq, 'D')
  494. self.assertEqual(result.name, expected.name)
  495. result_list = idx.tolist()
  496. for i in [0, 1, 3]:
  497. self.assertTrue(result_list[i], expected_list[i])
  498. self.assertTrue(result_list[2].ordinal, pd.tslib.iNaT)
  499. self.assertTrue(result_list[2].freq, 'D')
  500. def test_minmax(self):
  501. # monotonic
  502. idx1 = pd.PeriodIndex([pd.NaT, '2011-01-01', '2011-01-02',
  503. '2011-01-03'], freq='D')
  504. self.assertTrue(idx1.is_monotonic)
  505. # non-monotonic
  506. idx2 = pd.PeriodIndex(['2011-01-01', pd.NaT, '2011-01-03',
  507. '2011-01-02', pd.NaT], freq='D')
  508. self.assertFalse(idx2.is_monotonic)
  509. for idx in [idx1, idx2]:
  510. self.assertEqual(idx.min(), pd.Period('2011-01-01', freq='D'))
  511. self.assertEqual(idx.max(), pd.Period('2011-01-03', freq='D'))
  512. for op in ['min', 'max']:
  513. # Return NaT
  514. obj = PeriodIndex([], freq='M')
  515. result = getattr(obj, op)()
  516. self.assertEqual(result.ordinal, tslib.iNaT)
  517. self.assertEqual(result.freq, 'M')
  518. obj = PeriodIndex([pd.NaT], freq='M')
  519. result = getattr(obj, op)()
  520. self.assertEqual(result.ordinal, tslib.iNaT)
  521. self.assertEqual(result.freq, 'M')
  522. obj = PeriodIndex([pd.NaT, pd.NaT, pd.NaT], freq='M')
  523. result = getattr(obj, op)()
  524. self.assertEqual(result.ordinal, tslib.iNaT)
  525. self.assertEqual(result.freq, 'M')
  526. if __name__ == '__main__':
  527. import nose
  528. nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
  529. # '--with-coverage', '--cover-package=pandas.core'],
  530. exit=False)