test_panel.py 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621
  1. # -*- coding: utf-8 -*-
  2. # pylint: disable=W0612,E1101
  3. from datetime import datetime
  4. import operator
  5. from warnings import catch_warnings, simplefilter
  6. import numpy as np
  7. import pytest
  8. from pandas.compat import OrderedDict, StringIO, lrange, range, signature
  9. import pandas.util._test_decorators as td
  10. from pandas.core.dtypes.common import is_float_dtype
  11. from pandas import (
  12. DataFrame, Index, MultiIndex, Series, compat, date_range, isna, notna)
  13. from pandas.core.nanops import nanall, nanany
  14. import pandas.core.panel as panelm
  15. from pandas.core.panel import Panel
  16. import pandas.util.testing as tm
  17. from pandas.util.testing import (
  18. assert_almost_equal, assert_frame_equal, assert_panel_equal,
  19. assert_series_equal, ensure_clean, makeCustomDataframe as mkdf,
  20. makeMixedDataFrame)
  21. from pandas.io.formats.printing import pprint_thing
  22. from pandas.tseries.offsets import BDay, MonthEnd
  23. def make_test_panel():
  24. with catch_warnings(record=True):
  25. simplefilter("ignore", FutureWarning)
  26. _panel = tm.makePanel()
  27. tm.add_nans(_panel)
  28. _panel = _panel.copy()
  29. return _panel
  30. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  31. class PanelTests(object):
  32. panel = None
  33. def test_pickle(self):
  34. unpickled = tm.round_trip_pickle(self.panel)
  35. assert_frame_equal(unpickled['ItemA'], self.panel['ItemA'])
  36. def test_rank(self):
  37. pytest.raises(NotImplementedError, lambda: self.panel.rank())
  38. def test_cumsum(self):
  39. cumsum = self.panel.cumsum()
  40. assert_frame_equal(cumsum['ItemA'], self.panel['ItemA'].cumsum())
  41. def not_hashable(self):
  42. c_empty = Panel()
  43. c = Panel(Panel([[[1]]]))
  44. pytest.raises(TypeError, hash, c_empty)
  45. pytest.raises(TypeError, hash, c)
  46. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  47. class SafeForLongAndSparse(object):
  48. def test_repr(self):
  49. repr(self.panel)
  50. def test_copy_names(self):
  51. for attr in ('major_axis', 'minor_axis'):
  52. getattr(self.panel, attr).name = None
  53. cp = self.panel.copy()
  54. getattr(cp, attr).name = 'foo'
  55. assert getattr(self.panel, attr).name is None
  56. def test_iter(self):
  57. tm.equalContents(list(self.panel), self.panel.items)
  58. def test_count(self):
  59. f = lambda s: notna(s).sum()
  60. self._check_stat_op('count', f, obj=self.panel, has_skipna=False)
  61. def test_sum(self):
  62. self._check_stat_op('sum', np.sum, skipna_alternative=np.nansum)
  63. def test_mean(self):
  64. self._check_stat_op('mean', np.mean)
  65. def test_prod(self):
  66. self._check_stat_op('prod', np.prod, skipna_alternative=np.nanprod)
  67. @pytest.mark.filterwarnings("ignore:Invalid value:RuntimeWarning")
  68. @pytest.mark.filterwarnings("ignore:All-NaN:RuntimeWarning")
  69. def test_median(self):
  70. def wrapper(x):
  71. if isna(x).any():
  72. return np.nan
  73. return np.median(x)
  74. self._check_stat_op('median', wrapper)
  75. @pytest.mark.filterwarnings("ignore:Invalid value:RuntimeWarning")
  76. def test_min(self):
  77. self._check_stat_op('min', np.min)
  78. @pytest.mark.filterwarnings("ignore:Invalid value:RuntimeWarning")
  79. def test_max(self):
  80. self._check_stat_op('max', np.max)
  81. @td.skip_if_no_scipy
  82. def test_skew(self):
  83. from scipy.stats import skew
  84. def this_skew(x):
  85. if len(x) < 3:
  86. return np.nan
  87. return skew(x, bias=False)
  88. self._check_stat_op('skew', this_skew)
  89. def test_var(self):
  90. def alt(x):
  91. if len(x) < 2:
  92. return np.nan
  93. return np.var(x, ddof=1)
  94. self._check_stat_op('var', alt)
  95. def test_std(self):
  96. def alt(x):
  97. if len(x) < 2:
  98. return np.nan
  99. return np.std(x, ddof=1)
  100. self._check_stat_op('std', alt)
  101. def test_sem(self):
  102. def alt(x):
  103. if len(x) < 2:
  104. return np.nan
  105. return np.std(x, ddof=1) / np.sqrt(len(x))
  106. self._check_stat_op('sem', alt)
  107. def _check_stat_op(self, name, alternative, obj=None, has_skipna=True,
  108. skipna_alternative=None):
  109. if obj is None:
  110. obj = self.panel
  111. # # set some NAs
  112. # obj.loc[5:10] = np.nan
  113. # obj.loc[15:20, -2:] = np.nan
  114. f = getattr(obj, name)
  115. if has_skipna:
  116. skipna_wrapper = tm._make_skipna_wrapper(alternative,
  117. skipna_alternative)
  118. def wrapper(x):
  119. return alternative(np.asarray(x))
  120. for i in range(obj.ndim):
  121. result = f(axis=i, skipna=False)
  122. assert_frame_equal(result, obj.apply(wrapper, axis=i))
  123. else:
  124. skipna_wrapper = alternative
  125. wrapper = alternative
  126. for i in range(obj.ndim):
  127. result = f(axis=i)
  128. if name in ['sum', 'prod']:
  129. assert_frame_equal(result, obj.apply(skipna_wrapper, axis=i))
  130. pytest.raises(Exception, f, axis=obj.ndim)
  131. # Unimplemented numeric_only parameter.
  132. if 'numeric_only' in signature(f).args:
  133. with pytest.raises(NotImplementedError, match=name):
  134. f(numeric_only=True)
  135. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  136. class SafeForSparse(object):
  137. def test_get_axis(self):
  138. assert (self.panel._get_axis(0) is self.panel.items)
  139. assert (self.panel._get_axis(1) is self.panel.major_axis)
  140. assert (self.panel._get_axis(2) is self.panel.minor_axis)
  141. def test_set_axis(self):
  142. new_items = Index(np.arange(len(self.panel.items)))
  143. new_major = Index(np.arange(len(self.panel.major_axis)))
  144. new_minor = Index(np.arange(len(self.panel.minor_axis)))
  145. # ensure propagate to potentially prior-cached items too
  146. item = self.panel['ItemA']
  147. self.panel.items = new_items
  148. if hasattr(self.panel, '_item_cache'):
  149. assert 'ItemA' not in self.panel._item_cache
  150. assert self.panel.items is new_items
  151. # TODO: unused?
  152. item = self.panel[0] # noqa
  153. self.panel.major_axis = new_major
  154. assert self.panel[0].index is new_major
  155. assert self.panel.major_axis is new_major
  156. # TODO: unused?
  157. item = self.panel[0] # noqa
  158. self.panel.minor_axis = new_minor
  159. assert self.panel[0].columns is new_minor
  160. assert self.panel.minor_axis is new_minor
  161. def test_get_axis_number(self):
  162. assert self.panel._get_axis_number('items') == 0
  163. assert self.panel._get_axis_number('major') == 1
  164. assert self.panel._get_axis_number('minor') == 2
  165. with pytest.raises(ValueError, match="No axis named foo"):
  166. self.panel._get_axis_number('foo')
  167. with pytest.raises(ValueError, match="No axis named foo"):
  168. self.panel.__ge__(self.panel, axis='foo')
  169. def test_get_axis_name(self):
  170. assert self.panel._get_axis_name(0) == 'items'
  171. assert self.panel._get_axis_name(1) == 'major_axis'
  172. assert self.panel._get_axis_name(2) == 'minor_axis'
  173. def test_get_plane_axes(self):
  174. # what to do here?
  175. index, columns = self.panel._get_plane_axes('items')
  176. index, columns = self.panel._get_plane_axes('major_axis')
  177. index, columns = self.panel._get_plane_axes('minor_axis')
  178. index, columns = self.panel._get_plane_axes(0)
  179. def test_truncate(self):
  180. dates = self.panel.major_axis
  181. start, end = dates[1], dates[5]
  182. trunced = self.panel.truncate(start, end, axis='major')
  183. expected = self.panel['ItemA'].truncate(start, end)
  184. assert_frame_equal(trunced['ItemA'], expected)
  185. trunced = self.panel.truncate(before=start, axis='major')
  186. expected = self.panel['ItemA'].truncate(before=start)
  187. assert_frame_equal(trunced['ItemA'], expected)
  188. trunced = self.panel.truncate(after=end, axis='major')
  189. expected = self.panel['ItemA'].truncate(after=end)
  190. assert_frame_equal(trunced['ItemA'], expected)
  191. def test_arith(self):
  192. self._test_op(self.panel, operator.add)
  193. self._test_op(self.panel, operator.sub)
  194. self._test_op(self.panel, operator.mul)
  195. self._test_op(self.panel, operator.truediv)
  196. self._test_op(self.panel, operator.floordiv)
  197. self._test_op(self.panel, operator.pow)
  198. self._test_op(self.panel, lambda x, y: y + x)
  199. self._test_op(self.panel, lambda x, y: y - x)
  200. self._test_op(self.panel, lambda x, y: y * x)
  201. self._test_op(self.panel, lambda x, y: y / x)
  202. self._test_op(self.panel, lambda x, y: y ** x)
  203. self._test_op(self.panel, lambda x, y: x + y) # panel + 1
  204. self._test_op(self.panel, lambda x, y: x - y) # panel - 1
  205. self._test_op(self.panel, lambda x, y: x * y) # panel * 1
  206. self._test_op(self.panel, lambda x, y: x / y) # panel / 1
  207. self._test_op(self.panel, lambda x, y: x ** y) # panel ** 1
  208. pytest.raises(Exception, self.panel.__add__,
  209. self.panel['ItemA'])
  210. @staticmethod
  211. def _test_op(panel, op):
  212. result = op(panel, 1)
  213. assert_frame_equal(result['ItemA'], op(panel['ItemA'], 1))
  214. def test_keys(self):
  215. tm.equalContents(list(self.panel.keys()), self.panel.items)
  216. def test_iteritems(self):
  217. # Test panel.iteritems(), aka panel.iteritems()
  218. # just test that it works
  219. for k, v in self.panel.iteritems():
  220. pass
  221. assert len(list(self.panel.iteritems())) == len(self.panel.items)
  222. def test_combineFrame(self):
  223. def check_op(op, name):
  224. # items
  225. df = self.panel['ItemA']
  226. func = getattr(self.panel, name)
  227. result = func(df, axis='items')
  228. assert_frame_equal(
  229. result['ItemB'], op(self.panel['ItemB'], df))
  230. # major
  231. xs = self.panel.major_xs(self.panel.major_axis[0])
  232. result = func(xs, axis='major')
  233. idx = self.panel.major_axis[1]
  234. assert_frame_equal(result.major_xs(idx),
  235. op(self.panel.major_xs(idx), xs))
  236. # minor
  237. xs = self.panel.minor_xs(self.panel.minor_axis[0])
  238. result = func(xs, axis='minor')
  239. idx = self.panel.minor_axis[1]
  240. assert_frame_equal(result.minor_xs(idx),
  241. op(self.panel.minor_xs(idx), xs))
  242. ops = ['add', 'sub', 'mul', 'truediv', 'floordiv', 'pow', 'mod']
  243. if not compat.PY3:
  244. ops.append('div')
  245. for op in ops:
  246. try:
  247. check_op(getattr(operator, op), op)
  248. except AttributeError:
  249. pprint_thing("Failing operation: %r" % op)
  250. raise
  251. if compat.PY3:
  252. try:
  253. check_op(operator.truediv, 'div')
  254. except AttributeError:
  255. pprint_thing("Failing operation: %r" % 'div')
  256. raise
  257. def test_combinePanel(self):
  258. result = self.panel.add(self.panel)
  259. assert_panel_equal(result, self.panel * 2)
  260. def test_neg(self):
  261. assert_panel_equal(-self.panel, self.panel * -1)
  262. # issue 7692
  263. def test_raise_when_not_implemented(self):
  264. p = Panel(np.arange(3 * 4 * 5).reshape(3, 4, 5),
  265. items=['ItemA', 'ItemB', 'ItemC'],
  266. major_axis=date_range('20130101', periods=4),
  267. minor_axis=list('ABCDE'))
  268. d = p.sum(axis=1).iloc[0]
  269. ops = ['add', 'sub', 'mul', 'truediv',
  270. 'floordiv', 'div', 'mod', 'pow']
  271. for op in ops:
  272. with pytest.raises(NotImplementedError):
  273. getattr(p, op)(d, axis=0)
  274. def test_select(self):
  275. p = self.panel
  276. # select items
  277. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  278. result = p.select(lambda x: x in ('ItemA', 'ItemC'), axis='items')
  279. expected = p.reindex(items=['ItemA', 'ItemC'])
  280. assert_panel_equal(result, expected)
  281. # select major_axis
  282. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  283. result = p.select(lambda x: x >= datetime(
  284. 2000, 1, 15), axis='major')
  285. new_major = p.major_axis[p.major_axis >= datetime(2000, 1, 15)]
  286. expected = p.reindex(major=new_major)
  287. assert_panel_equal(result, expected)
  288. # select minor_axis
  289. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  290. result = p.select(lambda x: x in ('D', 'A'), axis=2)
  291. expected = p.reindex(minor=['A', 'D'])
  292. assert_panel_equal(result, expected)
  293. # corner case, empty thing
  294. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  295. result = p.select(lambda x: x in ('foo', ), axis='items')
  296. assert_panel_equal(result, p.reindex(items=[]))
  297. def test_get_value(self):
  298. for item in self.panel.items:
  299. for mjr in self.panel.major_axis[::2]:
  300. for mnr in self.panel.minor_axis:
  301. with tm.assert_produces_warning(FutureWarning,
  302. check_stacklevel=False):
  303. result = self.panel.get_value(item, mjr, mnr)
  304. expected = self.panel[item][mnr][mjr]
  305. assert_almost_equal(result, expected)
  306. def test_abs(self):
  307. result = self.panel.abs()
  308. result2 = abs(self.panel)
  309. expected = np.abs(self.panel)
  310. assert_panel_equal(result, expected)
  311. assert_panel_equal(result2, expected)
  312. df = self.panel['ItemA']
  313. result = df.abs()
  314. result2 = abs(df)
  315. expected = np.abs(df)
  316. assert_frame_equal(result, expected)
  317. assert_frame_equal(result2, expected)
  318. s = df['A']
  319. result = s.abs()
  320. result2 = abs(s)
  321. expected = np.abs(s)
  322. assert_series_equal(result, expected)
  323. assert_series_equal(result2, expected)
  324. assert result.name == 'A'
  325. assert result2.name == 'A'
  326. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  327. class CheckIndexing(object):
  328. def test_getitem(self):
  329. pytest.raises(Exception, self.panel.__getitem__, 'ItemQ')
  330. def test_delitem_and_pop(self):
  331. expected = self.panel['ItemA']
  332. result = self.panel.pop('ItemA')
  333. assert_frame_equal(expected, result)
  334. assert 'ItemA' not in self.panel.items
  335. del self.panel['ItemB']
  336. assert 'ItemB' not in self.panel.items
  337. pytest.raises(Exception, self.panel.__delitem__, 'ItemB')
  338. values = np.empty((3, 3, 3))
  339. values[0] = 0
  340. values[1] = 1
  341. values[2] = 2
  342. panel = Panel(values, lrange(3), lrange(3), lrange(3))
  343. # did we delete the right row?
  344. panelc = panel.copy()
  345. del panelc[0]
  346. tm.assert_frame_equal(panelc[1], panel[1])
  347. tm.assert_frame_equal(panelc[2], panel[2])
  348. panelc = panel.copy()
  349. del panelc[1]
  350. tm.assert_frame_equal(panelc[0], panel[0])
  351. tm.assert_frame_equal(panelc[2], panel[2])
  352. panelc = panel.copy()
  353. del panelc[2]
  354. tm.assert_frame_equal(panelc[1], panel[1])
  355. tm.assert_frame_equal(panelc[0], panel[0])
  356. def test_setitem(self):
  357. lp = self.panel.filter(['ItemA', 'ItemB']).to_frame()
  358. with pytest.raises(TypeError):
  359. self.panel['ItemE'] = lp
  360. # DataFrame
  361. df = self.panel['ItemA'][2:].filter(items=['A', 'B'])
  362. self.panel['ItemF'] = df
  363. self.panel['ItemE'] = df
  364. df2 = self.panel['ItemF']
  365. assert_frame_equal(df, df2.reindex(
  366. index=df.index, columns=df.columns))
  367. # scalar
  368. self.panel['ItemG'] = 1
  369. self.panel['ItemE'] = True
  370. assert self.panel['ItemG'].values.dtype == np.int64
  371. assert self.panel['ItemE'].values.dtype == np.bool_
  372. # object dtype
  373. self.panel['ItemQ'] = 'foo'
  374. assert self.panel['ItemQ'].values.dtype == np.object_
  375. # boolean dtype
  376. self.panel['ItemP'] = self.panel['ItemA'] > 0
  377. assert self.panel['ItemP'].values.dtype == np.bool_
  378. pytest.raises(TypeError, self.panel.__setitem__, 'foo',
  379. self.panel.loc[['ItemP']])
  380. # bad shape
  381. p = Panel(np.random.randn(4, 3, 2))
  382. msg = (r"shape of value must be \(3, 2\), "
  383. r"shape of given object was \(4, 2\)")
  384. with pytest.raises(ValueError, match=msg):
  385. p[0] = np.random.randn(4, 2)
  386. def test_setitem_ndarray(self):
  387. timeidx = date_range(start=datetime(2009, 1, 1),
  388. end=datetime(2009, 12, 31),
  389. freq=MonthEnd())
  390. lons_coarse = np.linspace(-177.5, 177.5, 72)
  391. lats_coarse = np.linspace(-87.5, 87.5, 36)
  392. P = Panel(items=timeidx, major_axis=lons_coarse,
  393. minor_axis=lats_coarse)
  394. data = np.random.randn(72 * 36).reshape((72, 36))
  395. key = datetime(2009, 2, 28)
  396. P[key] = data
  397. assert_almost_equal(P[key].values, data)
  398. def test_set_minor_major(self):
  399. # GH 11014
  400. df1 = DataFrame(['a', 'a', 'a', np.nan, 'a', np.nan])
  401. df2 = DataFrame([1.0, np.nan, 1.0, np.nan, 1.0, 1.0])
  402. panel = Panel({'Item1': df1, 'Item2': df2})
  403. newminor = notna(panel.iloc[:, :, 0])
  404. panel.loc[:, :, 'NewMinor'] = newminor
  405. assert_frame_equal(panel.loc[:, :, 'NewMinor'],
  406. newminor.astype(object))
  407. newmajor = notna(panel.iloc[:, 0, :])
  408. panel.loc[:, 'NewMajor', :] = newmajor
  409. assert_frame_equal(panel.loc[:, 'NewMajor', :],
  410. newmajor.astype(object))
  411. def test_major_xs(self):
  412. ref = self.panel['ItemA']
  413. idx = self.panel.major_axis[5]
  414. xs = self.panel.major_xs(idx)
  415. result = xs['ItemA']
  416. assert_series_equal(result, ref.xs(idx), check_names=False)
  417. assert result.name == 'ItemA'
  418. # not contained
  419. idx = self.panel.major_axis[0] - BDay()
  420. pytest.raises(Exception, self.panel.major_xs, idx)
  421. def test_major_xs_mixed(self):
  422. self.panel['ItemD'] = 'foo'
  423. xs = self.panel.major_xs(self.panel.major_axis[0])
  424. assert xs['ItemA'].dtype == np.float64
  425. assert xs['ItemD'].dtype == np.object_
  426. def test_minor_xs(self):
  427. ref = self.panel['ItemA']
  428. idx = self.panel.minor_axis[1]
  429. xs = self.panel.minor_xs(idx)
  430. assert_series_equal(xs['ItemA'], ref[idx], check_names=False)
  431. # not contained
  432. pytest.raises(Exception, self.panel.minor_xs, 'E')
  433. def test_minor_xs_mixed(self):
  434. self.panel['ItemD'] = 'foo'
  435. xs = self.panel.minor_xs('D')
  436. assert xs['ItemA'].dtype == np.float64
  437. assert xs['ItemD'].dtype == np.object_
  438. def test_xs(self):
  439. itemA = self.panel.xs('ItemA', axis=0)
  440. expected = self.panel['ItemA']
  441. tm.assert_frame_equal(itemA, expected)
  442. # Get a view by default.
  443. itemA_view = self.panel.xs('ItemA', axis=0)
  444. itemA_view.values[:] = np.nan
  445. assert np.isnan(self.panel['ItemA'].values).all()
  446. # Mixed-type yields a copy.
  447. self.panel['strings'] = 'foo'
  448. result = self.panel.xs('D', axis=2)
  449. assert result._is_copy is not None
  450. def test_getitem_fancy_labels(self):
  451. p = self.panel
  452. items = p.items[[1, 0]]
  453. dates = p.major_axis[::2]
  454. cols = ['D', 'C', 'F']
  455. # all 3 specified
  456. with catch_warnings():
  457. simplefilter("ignore", FutureWarning)
  458. # XXX: warning in _validate_read_indexer
  459. assert_panel_equal(p.loc[items, dates, cols],
  460. p.reindex(items=items, major=dates, minor=cols))
  461. # 2 specified
  462. assert_panel_equal(p.loc[:, dates, cols],
  463. p.reindex(major=dates, minor=cols))
  464. assert_panel_equal(p.loc[items, :, cols],
  465. p.reindex(items=items, minor=cols))
  466. assert_panel_equal(p.loc[items, dates, :],
  467. p.reindex(items=items, major=dates))
  468. # only 1
  469. assert_panel_equal(p.loc[items, :, :], p.reindex(items=items))
  470. assert_panel_equal(p.loc[:, dates, :], p.reindex(major=dates))
  471. assert_panel_equal(p.loc[:, :, cols], p.reindex(minor=cols))
  472. def test_getitem_fancy_slice(self):
  473. pass
  474. def test_getitem_fancy_ints(self):
  475. p = self.panel
  476. # #1603
  477. result = p.iloc[:, -1, :]
  478. expected = p.loc[:, p.major_axis[-1], :]
  479. assert_frame_equal(result, expected)
  480. def test_getitem_fancy_xs(self):
  481. p = self.panel
  482. item = 'ItemB'
  483. date = p.major_axis[5]
  484. col = 'C'
  485. # get DataFrame
  486. # item
  487. assert_frame_equal(p.loc[item], p[item])
  488. assert_frame_equal(p.loc[item, :], p[item])
  489. assert_frame_equal(p.loc[item, :, :], p[item])
  490. # major axis, axis=1
  491. assert_frame_equal(p.loc[:, date], p.major_xs(date))
  492. assert_frame_equal(p.loc[:, date, :], p.major_xs(date))
  493. # minor axis, axis=2
  494. assert_frame_equal(p.loc[:, :, 'C'], p.minor_xs('C'))
  495. # get Series
  496. assert_series_equal(p.loc[item, date], p[item].loc[date])
  497. assert_series_equal(p.loc[item, date, :], p[item].loc[date])
  498. assert_series_equal(p.loc[item, :, col], p[item][col])
  499. assert_series_equal(p.loc[:, date, col], p.major_xs(date).loc[col])
  500. def test_getitem_fancy_xs_check_view(self):
  501. item = 'ItemB'
  502. date = self.panel.major_axis[5]
  503. # make sure it's always a view
  504. NS = slice(None, None)
  505. # DataFrames
  506. comp = assert_frame_equal
  507. self._check_view(item, comp)
  508. self._check_view((item, NS), comp)
  509. self._check_view((item, NS, NS), comp)
  510. self._check_view((NS, date), comp)
  511. self._check_view((NS, date, NS), comp)
  512. self._check_view((NS, NS, 'C'), comp)
  513. # Series
  514. comp = assert_series_equal
  515. self._check_view((item, date), comp)
  516. self._check_view((item, date, NS), comp)
  517. self._check_view((item, NS, 'C'), comp)
  518. self._check_view((NS, date, 'C'), comp)
  519. def test_getitem_callable(self):
  520. p = self.panel
  521. # GH 12533
  522. assert_frame_equal(p[lambda x: 'ItemB'], p.loc['ItemB'])
  523. assert_panel_equal(p[lambda x: ['ItemB', 'ItemC']],
  524. p.loc[['ItemB', 'ItemC']])
  525. def test_ix_setitem_slice_dataframe(self):
  526. a = Panel(items=[1, 2, 3], major_axis=[11, 22, 33],
  527. minor_axis=[111, 222, 333])
  528. b = DataFrame(np.random.randn(2, 3), index=[111, 333],
  529. columns=[1, 2, 3])
  530. a.loc[:, 22, [111, 333]] = b
  531. assert_frame_equal(a.loc[:, 22, [111, 333]], b)
  532. def test_ix_align(self):
  533. from pandas import Series
  534. b = Series(np.random.randn(10), name=0)
  535. b.sort_values()
  536. df_orig = Panel(np.random.randn(3, 10, 2))
  537. df = df_orig.copy()
  538. df.loc[0, :, 0] = b
  539. assert_series_equal(df.loc[0, :, 0].reindex(b.index), b)
  540. df = df_orig.swapaxes(0, 1)
  541. df.loc[:, 0, 0] = b
  542. assert_series_equal(df.loc[:, 0, 0].reindex(b.index), b)
  543. df = df_orig.swapaxes(1, 2)
  544. df.loc[0, 0, :] = b
  545. assert_series_equal(df.loc[0, 0, :].reindex(b.index), b)
  546. def test_ix_frame_align(self):
  547. p_orig = tm.makePanel()
  548. df = p_orig.iloc[0].copy()
  549. assert_frame_equal(p_orig['ItemA'], df)
  550. p = p_orig.copy()
  551. p.iloc[0, :, :] = df
  552. assert_panel_equal(p, p_orig)
  553. p = p_orig.copy()
  554. p.iloc[0] = df
  555. assert_panel_equal(p, p_orig)
  556. p = p_orig.copy()
  557. p.iloc[0, :, :] = df
  558. assert_panel_equal(p, p_orig)
  559. p = p_orig.copy()
  560. p.iloc[0] = df
  561. assert_panel_equal(p, p_orig)
  562. p = p_orig.copy()
  563. p.loc['ItemA'] = df
  564. assert_panel_equal(p, p_orig)
  565. p = p_orig.copy()
  566. p.loc['ItemA', :, :] = df
  567. assert_panel_equal(p, p_orig)
  568. p = p_orig.copy()
  569. p['ItemA'] = df
  570. assert_panel_equal(p, p_orig)
  571. p = p_orig.copy()
  572. p.iloc[0, [0, 1, 3, 5], -2:] = df
  573. out = p.iloc[0, [0, 1, 3, 5], -2:]
  574. assert_frame_equal(out, df.iloc[[0, 1, 3, 5], [2, 3]])
  575. # GH3830, panel assignent by values/frame
  576. for dtype in ['float64', 'int64']:
  577. panel = Panel(np.arange(40).reshape((2, 4, 5)),
  578. items=['a1', 'a2'], dtype=dtype)
  579. df1 = panel.iloc[0]
  580. df2 = panel.iloc[1]
  581. tm.assert_frame_equal(panel.loc['a1'], df1)
  582. tm.assert_frame_equal(panel.loc['a2'], df2)
  583. # Assignment by Value Passes for 'a2'
  584. panel.loc['a2'] = df1.values
  585. tm.assert_frame_equal(panel.loc['a1'], df1)
  586. tm.assert_frame_equal(panel.loc['a2'], df1)
  587. # Assignment by DataFrame Ok w/o loc 'a2'
  588. panel['a2'] = df2
  589. tm.assert_frame_equal(panel.loc['a1'], df1)
  590. tm.assert_frame_equal(panel.loc['a2'], df2)
  591. # Assignment by DataFrame Fails for 'a2'
  592. panel.loc['a2'] = df2
  593. tm.assert_frame_equal(panel.loc['a1'], df1)
  594. tm.assert_frame_equal(panel.loc['a2'], df2)
  595. def _check_view(self, indexer, comp):
  596. cp = self.panel.copy()
  597. obj = cp.loc[indexer]
  598. obj.values[:] = 0
  599. assert (obj.values == 0).all()
  600. comp(cp.loc[indexer].reindex_like(obj), obj)
  601. def test_logical_with_nas(self):
  602. d = Panel({'ItemA': {'a': [np.nan, False]},
  603. 'ItemB': {'a': [True, True]}})
  604. result = d['ItemA'] | d['ItemB']
  605. expected = DataFrame({'a': [np.nan, True]})
  606. assert_frame_equal(result, expected)
  607. # this is autodowncasted here
  608. result = d['ItemA'].fillna(False) | d['ItemB']
  609. expected = DataFrame({'a': [True, True]})
  610. assert_frame_equal(result, expected)
  611. def test_neg(self):
  612. assert_panel_equal(-self.panel, -1 * self.panel)
  613. def test_invert(self):
  614. assert_panel_equal(-(self.panel < 0), ~(self.panel < 0))
  615. def test_comparisons(self):
  616. p1 = tm.makePanel()
  617. p2 = tm.makePanel()
  618. tp = p1.reindex(items=p1.items + ['foo'])
  619. df = p1[p1.items[0]]
  620. def test_comp(func):
  621. # versus same index
  622. result = func(p1, p2)
  623. tm.assert_numpy_array_equal(result.values,
  624. func(p1.values, p2.values))
  625. # versus non-indexed same objs
  626. pytest.raises(Exception, func, p1, tp)
  627. # versus different objs
  628. pytest.raises(Exception, func, p1, df)
  629. # versus scalar
  630. result3 = func(self.panel, 0)
  631. tm.assert_numpy_array_equal(result3.values,
  632. func(self.panel.values, 0))
  633. with np.errstate(invalid='ignore'):
  634. test_comp(operator.eq)
  635. test_comp(operator.ne)
  636. test_comp(operator.lt)
  637. test_comp(operator.gt)
  638. test_comp(operator.ge)
  639. test_comp(operator.le)
  640. def test_get_value(self):
  641. for item in self.panel.items:
  642. for mjr in self.panel.major_axis[::2]:
  643. for mnr in self.panel.minor_axis:
  644. with tm.assert_produces_warning(FutureWarning,
  645. check_stacklevel=False):
  646. result = self.panel.get_value(item, mjr, mnr)
  647. expected = self.panel[item][mnr][mjr]
  648. assert_almost_equal(result, expected)
  649. with catch_warnings():
  650. simplefilter("ignore", FutureWarning)
  651. msg = "There must be an argument for each axis"
  652. with pytest.raises(TypeError, match=msg):
  653. self.panel.get_value('a')
  654. def test_set_value(self):
  655. for item in self.panel.items:
  656. for mjr in self.panel.major_axis[::2]:
  657. for mnr in self.panel.minor_axis:
  658. with tm.assert_produces_warning(FutureWarning,
  659. check_stacklevel=False):
  660. self.panel.set_value(item, mjr, mnr, 1.)
  661. tm.assert_almost_equal(self.panel[item][mnr][mjr], 1.)
  662. # resize
  663. with catch_warnings():
  664. simplefilter("ignore", FutureWarning)
  665. res = self.panel.set_value('ItemE', 'foo', 'bar', 1.5)
  666. assert isinstance(res, Panel)
  667. assert res is not self.panel
  668. assert res.get_value('ItemE', 'foo', 'bar') == 1.5
  669. res3 = self.panel.set_value('ItemE', 'foobar', 'baz', 5)
  670. assert is_float_dtype(res3['ItemE'].values)
  671. msg = ("There must be an argument for each "
  672. "axis plus the value provided")
  673. with pytest.raises(TypeError, match=msg):
  674. self.panel.set_value('a')
  675. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  676. class TestPanel(PanelTests, CheckIndexing, SafeForLongAndSparse,
  677. SafeForSparse):
  678. def setup_method(self, method):
  679. self.panel = make_test_panel()
  680. self.panel.major_axis.name = None
  681. self.panel.minor_axis.name = None
  682. self.panel.items.name = None
  683. def test_constructor(self):
  684. # with BlockManager
  685. wp = Panel(self.panel._data)
  686. assert wp._data is self.panel._data
  687. wp = Panel(self.panel._data, copy=True)
  688. assert wp._data is not self.panel._data
  689. tm.assert_panel_equal(wp, self.panel)
  690. # strings handled prop
  691. wp = Panel([[['foo', 'foo', 'foo', ], ['foo', 'foo', 'foo']]])
  692. assert wp.values.dtype == np.object_
  693. vals = self.panel.values
  694. # no copy
  695. wp = Panel(vals)
  696. assert wp.values is vals
  697. # copy
  698. wp = Panel(vals, copy=True)
  699. assert wp.values is not vals
  700. # GH #8285, test when scalar data is used to construct a Panel
  701. # if dtype is not passed, it should be inferred
  702. value_and_dtype = [(1, 'int64'), (3.14, 'float64'),
  703. ('foo', np.object_)]
  704. for (val, dtype) in value_and_dtype:
  705. wp = Panel(val, items=range(2), major_axis=range(3),
  706. minor_axis=range(4))
  707. vals = np.empty((2, 3, 4), dtype=dtype)
  708. vals.fill(val)
  709. tm.assert_panel_equal(wp, Panel(vals, dtype=dtype))
  710. # test the case when dtype is passed
  711. wp = Panel(1, items=range(2), major_axis=range(3),
  712. minor_axis=range(4),
  713. dtype='float32')
  714. vals = np.empty((2, 3, 4), dtype='float32')
  715. vals.fill(1)
  716. tm.assert_panel_equal(wp, Panel(vals, dtype='float32'))
  717. def test_constructor_cast(self):
  718. zero_filled = self.panel.fillna(0)
  719. casted = Panel(zero_filled._data, dtype=int)
  720. casted2 = Panel(zero_filled.values, dtype=int)
  721. exp_values = zero_filled.values.astype(int)
  722. assert_almost_equal(casted.values, exp_values)
  723. assert_almost_equal(casted2.values, exp_values)
  724. casted = Panel(zero_filled._data, dtype=np.int32)
  725. casted2 = Panel(zero_filled.values, dtype=np.int32)
  726. exp_values = zero_filled.values.astype(np.int32)
  727. assert_almost_equal(casted.values, exp_values)
  728. assert_almost_equal(casted2.values, exp_values)
  729. # can't cast
  730. data = [[['foo', 'bar', 'baz']]]
  731. pytest.raises(ValueError, Panel, data, dtype=float)
  732. def test_constructor_empty_panel(self):
  733. empty = Panel()
  734. assert len(empty.items) == 0
  735. assert len(empty.major_axis) == 0
  736. assert len(empty.minor_axis) == 0
  737. def test_constructor_observe_dtype(self):
  738. # GH #411
  739. panel = Panel(items=lrange(3), major_axis=lrange(3),
  740. minor_axis=lrange(3), dtype='O')
  741. assert panel.values.dtype == np.object_
  742. def test_constructor_dtypes(self):
  743. # GH #797
  744. def _check_dtype(panel, dtype):
  745. for i in panel.items:
  746. assert panel[i].values.dtype.name == dtype
  747. # only nan holding types allowed here
  748. for dtype in ['float64', 'float32', 'object']:
  749. panel = Panel(items=lrange(2), major_axis=lrange(10),
  750. minor_axis=lrange(5), dtype=dtype)
  751. _check_dtype(panel, dtype)
  752. for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
  753. panel = Panel(np.array(np.random.randn(2, 10, 5), dtype=dtype),
  754. items=lrange(2),
  755. major_axis=lrange(10),
  756. minor_axis=lrange(5), dtype=dtype)
  757. _check_dtype(panel, dtype)
  758. for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
  759. panel = Panel(np.array(np.random.randn(2, 10, 5), dtype='O'),
  760. items=lrange(2),
  761. major_axis=lrange(10),
  762. minor_axis=lrange(5), dtype=dtype)
  763. _check_dtype(panel, dtype)
  764. for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
  765. panel = Panel(
  766. np.random.randn(2, 10, 5),
  767. items=lrange(2), major_axis=lrange(10),
  768. minor_axis=lrange(5),
  769. dtype=dtype)
  770. _check_dtype(panel, dtype)
  771. for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
  772. df1 = DataFrame(np.random.randn(2, 5),
  773. index=lrange(2), columns=lrange(5))
  774. df2 = DataFrame(np.random.randn(2, 5),
  775. index=lrange(2), columns=lrange(5))
  776. panel = Panel.from_dict({'a': df1, 'b': df2}, dtype=dtype)
  777. _check_dtype(panel, dtype)
  778. def test_constructor_fails_with_not_3d_input(self):
  779. msg = "The number of dimensions required is 3"
  780. with pytest.raises(ValueError, match=msg):
  781. Panel(np.random.randn(10, 2))
  782. def test_consolidate(self):
  783. assert self.panel._data.is_consolidated()
  784. self.panel['foo'] = 1.
  785. assert not self.panel._data.is_consolidated()
  786. panel = self.panel._consolidate()
  787. assert panel._data.is_consolidated()
  788. def test_ctor_dict(self):
  789. itema = self.panel['ItemA']
  790. itemb = self.panel['ItemB']
  791. d = {'A': itema, 'B': itemb[5:]}
  792. d2 = {'A': itema._series, 'B': itemb[5:]._series}
  793. d3 = {'A': None,
  794. 'B': DataFrame(itemb[5:]._series),
  795. 'C': DataFrame(itema._series)}
  796. wp = Panel.from_dict(d)
  797. wp2 = Panel.from_dict(d2) # nested Dict
  798. # TODO: unused?
  799. wp3 = Panel.from_dict(d3) # noqa
  800. tm.assert_index_equal(wp.major_axis, self.panel.major_axis)
  801. assert_panel_equal(wp, wp2)
  802. # intersect
  803. wp = Panel.from_dict(d, intersect=True)
  804. tm.assert_index_equal(wp.major_axis, itemb.index[5:])
  805. # use constructor
  806. assert_panel_equal(Panel(d), Panel.from_dict(d))
  807. assert_panel_equal(Panel(d2), Panel.from_dict(d2))
  808. assert_panel_equal(Panel(d3), Panel.from_dict(d3))
  809. # a pathological case
  810. d4 = {'A': None, 'B': None}
  811. # TODO: unused?
  812. wp4 = Panel.from_dict(d4) # noqa
  813. assert_panel_equal(Panel(d4), Panel(items=['A', 'B']))
  814. # cast
  815. dcasted = {k: v.reindex(wp.major_axis).fillna(0)
  816. for k, v in compat.iteritems(d)}
  817. result = Panel(dcasted, dtype=int)
  818. expected = Panel({k: v.astype(int)
  819. for k, v in compat.iteritems(dcasted)})
  820. assert_panel_equal(result, expected)
  821. result = Panel(dcasted, dtype=np.int32)
  822. expected = Panel({k: v.astype(np.int32)
  823. for k, v in compat.iteritems(dcasted)})
  824. assert_panel_equal(result, expected)
  825. def test_constructor_dict_mixed(self):
  826. data = {k: v.values for k, v in self.panel.iteritems()}
  827. result = Panel(data)
  828. exp_major = Index(np.arange(len(self.panel.major_axis)))
  829. tm.assert_index_equal(result.major_axis, exp_major)
  830. result = Panel(data, items=self.panel.items,
  831. major_axis=self.panel.major_axis,
  832. minor_axis=self.panel.minor_axis)
  833. assert_panel_equal(result, self.panel)
  834. data['ItemC'] = self.panel['ItemC']
  835. result = Panel(data)
  836. assert_panel_equal(result, self.panel)
  837. # corner, blow up
  838. data['ItemB'] = data['ItemB'][:-1]
  839. pytest.raises(Exception, Panel, data)
  840. data['ItemB'] = self.panel['ItemB'].values[:, :-1]
  841. pytest.raises(Exception, Panel, data)
  842. def test_ctor_orderedDict(self):
  843. keys = list(set(np.random.randint(0, 5000, 100)))[
  844. :50] # unique random int keys
  845. d = OrderedDict([(k, mkdf(10, 5)) for k in keys])
  846. p = Panel(d)
  847. assert list(p.items) == keys
  848. p = Panel.from_dict(d)
  849. assert list(p.items) == keys
  850. def test_constructor_resize(self):
  851. data = self.panel._data
  852. items = self.panel.items[:-1]
  853. major = self.panel.major_axis[:-1]
  854. minor = self.panel.minor_axis[:-1]
  855. result = Panel(data, items=items,
  856. major_axis=major, minor_axis=minor)
  857. expected = self.panel.reindex(
  858. items=items, major=major, minor=minor)
  859. assert_panel_equal(result, expected)
  860. result = Panel(data, items=items, major_axis=major)
  861. expected = self.panel.reindex(items=items, major=major)
  862. assert_panel_equal(result, expected)
  863. result = Panel(data, items=items)
  864. expected = self.panel.reindex(items=items)
  865. assert_panel_equal(result, expected)
  866. result = Panel(data, minor_axis=minor)
  867. expected = self.panel.reindex(minor=minor)
  868. assert_panel_equal(result, expected)
  869. def test_from_dict_mixed_orient(self):
  870. df = tm.makeDataFrame()
  871. df['foo'] = 'bar'
  872. data = {'k1': df, 'k2': df}
  873. panel = Panel.from_dict(data, orient='minor')
  874. assert panel['foo'].values.dtype == np.object_
  875. assert panel['A'].values.dtype == np.float64
  876. def test_constructor_error_msgs(self):
  877. msg = (r"Shape of passed values is \(3, 4, 5\), "
  878. r"indices imply \(4, 5, 5\)")
  879. with pytest.raises(ValueError, match=msg):
  880. Panel(np.random.randn(3, 4, 5),
  881. lrange(4), lrange(5), lrange(5))
  882. msg = (r"Shape of passed values is \(3, 4, 5\), "
  883. r"indices imply \(5, 4, 5\)")
  884. with pytest.raises(ValueError, match=msg):
  885. Panel(np.random.randn(3, 4, 5),
  886. lrange(5), lrange(4), lrange(5))
  887. msg = (r"Shape of passed values is \(3, 4, 5\), "
  888. r"indices imply \(5, 5, 4\)")
  889. with pytest.raises(ValueError, match=msg):
  890. Panel(np.random.randn(3, 4, 5),
  891. lrange(5), lrange(5), lrange(4))
  892. def test_conform(self):
  893. df = self.panel['ItemA'][:-5].filter(items=['A', 'B'])
  894. conformed = self.panel.conform(df)
  895. tm.assert_index_equal(conformed.index, self.panel.major_axis)
  896. tm.assert_index_equal(conformed.columns, self.panel.minor_axis)
  897. def test_convert_objects(self):
  898. # GH 4937
  899. p = Panel(dict(A=dict(a=['1', '1.0'])))
  900. expected = Panel(dict(A=dict(a=[1, 1.0])))
  901. result = p._convert(numeric=True, coerce=True)
  902. assert_panel_equal(result, expected)
  903. def test_dtypes(self):
  904. result = self.panel.dtypes
  905. expected = Series(np.dtype('float64'), index=self.panel.items)
  906. assert_series_equal(result, expected)
  907. def test_astype(self):
  908. # GH7271
  909. data = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
  910. panel = Panel(data, ['a', 'b'], ['c', 'd'], ['e', 'f'])
  911. str_data = np.array([[['1', '2'], ['3', '4']],
  912. [['5', '6'], ['7', '8']]])
  913. expected = Panel(str_data, ['a', 'b'], ['c', 'd'], ['e', 'f'])
  914. assert_panel_equal(panel.astype(str), expected)
  915. pytest.raises(NotImplementedError, panel.astype, {0: str})
  916. def test_apply(self):
  917. # GH1148
  918. # ufunc
  919. applied = self.panel.apply(np.sqrt)
  920. with np.errstate(invalid='ignore'):
  921. expected = np.sqrt(self.panel.values)
  922. assert_almost_equal(applied.values, expected)
  923. # ufunc same shape
  924. result = self.panel.apply(lambda x: x * 2, axis='items')
  925. expected = self.panel * 2
  926. assert_panel_equal(result, expected)
  927. result = self.panel.apply(lambda x: x * 2, axis='major_axis')
  928. expected = self.panel * 2
  929. assert_panel_equal(result, expected)
  930. result = self.panel.apply(lambda x: x * 2, axis='minor_axis')
  931. expected = self.panel * 2
  932. assert_panel_equal(result, expected)
  933. # reduction to DataFrame
  934. result = self.panel.apply(lambda x: x.dtype, axis='items')
  935. expected = DataFrame(np.dtype('float64'),
  936. index=self.panel.major_axis,
  937. columns=self.panel.minor_axis)
  938. assert_frame_equal(result, expected)
  939. result = self.panel.apply(lambda x: x.dtype, axis='major_axis')
  940. expected = DataFrame(np.dtype('float64'),
  941. index=self.panel.minor_axis,
  942. columns=self.panel.items)
  943. assert_frame_equal(result, expected)
  944. result = self.panel.apply(lambda x: x.dtype, axis='minor_axis')
  945. expected = DataFrame(np.dtype('float64'),
  946. index=self.panel.major_axis,
  947. columns=self.panel.items)
  948. assert_frame_equal(result, expected)
  949. # reductions via other dims
  950. expected = self.panel.sum(0)
  951. result = self.panel.apply(lambda x: x.sum(), axis='items')
  952. assert_frame_equal(result, expected)
  953. expected = self.panel.sum(1)
  954. result = self.panel.apply(lambda x: x.sum(), axis='major_axis')
  955. assert_frame_equal(result, expected)
  956. expected = self.panel.sum(2)
  957. result = self.panel.apply(lambda x: x.sum(), axis='minor_axis')
  958. assert_frame_equal(result, expected)
  959. # pass kwargs
  960. result = self.panel.apply(
  961. lambda x, y: x.sum() + y, axis='items', y=5)
  962. expected = self.panel.sum(0) + 5
  963. assert_frame_equal(result, expected)
  964. def test_apply_slabs(self):
  965. # same shape as original
  966. result = self.panel.apply(lambda x: x * 2,
  967. axis=['items', 'major_axis'])
  968. expected = (self.panel * 2).transpose('minor_axis', 'major_axis',
  969. 'items')
  970. assert_panel_equal(result, expected)
  971. result = self.panel.apply(lambda x: x * 2,
  972. axis=['major_axis', 'items'])
  973. assert_panel_equal(result, expected)
  974. result = self.panel.apply(lambda x: x * 2,
  975. axis=['items', 'minor_axis'])
  976. expected = (self.panel * 2).transpose('major_axis', 'minor_axis',
  977. 'items')
  978. assert_panel_equal(result, expected)
  979. result = self.panel.apply(lambda x: x * 2,
  980. axis=['minor_axis', 'items'])
  981. assert_panel_equal(result, expected)
  982. result = self.panel.apply(lambda x: x * 2,
  983. axis=['major_axis', 'minor_axis'])
  984. expected = self.panel * 2
  985. assert_panel_equal(result, expected)
  986. result = self.panel.apply(lambda x: x * 2,
  987. axis=['minor_axis', 'major_axis'])
  988. assert_panel_equal(result, expected)
  989. # reductions
  990. result = self.panel.apply(lambda x: x.sum(0), axis=[
  991. 'items', 'major_axis'
  992. ])
  993. expected = self.panel.sum(1).T
  994. assert_frame_equal(result, expected)
  995. result = self.panel.apply(lambda x: x.sum(1), axis=[
  996. 'items', 'major_axis'
  997. ])
  998. expected = self.panel.sum(0)
  999. assert_frame_equal(result, expected)
  1000. # transforms
  1001. f = lambda x: ((x.T - x.mean(1)) / x.std(1)).T
  1002. # make sure that we don't trigger any warnings
  1003. result = self.panel.apply(f, axis=['items', 'major_axis'])
  1004. expected = Panel({ax: f(self.panel.loc[:, :, ax])
  1005. for ax in self.panel.minor_axis})
  1006. assert_panel_equal(result, expected)
  1007. result = self.panel.apply(f, axis=['major_axis', 'minor_axis'])
  1008. expected = Panel({ax: f(self.panel.loc[ax])
  1009. for ax in self.panel.items})
  1010. assert_panel_equal(result, expected)
  1011. result = self.panel.apply(f, axis=['minor_axis', 'items'])
  1012. expected = Panel({ax: f(self.panel.loc[:, ax])
  1013. for ax in self.panel.major_axis})
  1014. assert_panel_equal(result, expected)
  1015. # with multi-indexes
  1016. # GH7469
  1017. index = MultiIndex.from_tuples([('one', 'a'), ('one', 'b'), (
  1018. 'two', 'a'), ('two', 'b')])
  1019. dfa = DataFrame(np.array(np.arange(12, dtype='int64')).reshape(
  1020. 4, 3), columns=list("ABC"), index=index)
  1021. dfb = DataFrame(np.array(np.arange(10, 22, dtype='int64')).reshape(
  1022. 4, 3), columns=list("ABC"), index=index)
  1023. p = Panel({'f': dfa, 'g': dfb})
  1024. result = p.apply(lambda x: x.sum(), axis=0)
  1025. # on windows this will be in32
  1026. result = result.astype('int64')
  1027. expected = p.sum(0)
  1028. assert_frame_equal(result, expected)
  1029. def test_apply_no_or_zero_ndim(self):
  1030. # GH10332
  1031. self.panel = Panel(np.random.rand(5, 5, 5))
  1032. result_int = self.panel.apply(lambda df: 0, axis=[1, 2])
  1033. result_float = self.panel.apply(lambda df: 0.0, axis=[1, 2])
  1034. result_int64 = self.panel.apply(
  1035. lambda df: np.int64(0), axis=[1, 2])
  1036. result_float64 = self.panel.apply(lambda df: np.float64(0.0),
  1037. axis=[1, 2])
  1038. expected_int = expected_int64 = Series([0] * 5)
  1039. expected_float = expected_float64 = Series([0.0] * 5)
  1040. assert_series_equal(result_int, expected_int)
  1041. assert_series_equal(result_int64, expected_int64)
  1042. assert_series_equal(result_float, expected_float)
  1043. assert_series_equal(result_float64, expected_float64)
  1044. def test_reindex(self):
  1045. ref = self.panel['ItemB']
  1046. # items
  1047. result = self.panel.reindex(items=['ItemA', 'ItemB'])
  1048. assert_frame_equal(result['ItemB'], ref)
  1049. # major
  1050. new_major = list(self.panel.major_axis[:10])
  1051. result = self.panel.reindex(major=new_major)
  1052. assert_frame_equal(result['ItemB'], ref.reindex(index=new_major))
  1053. # raise exception put both major and major_axis
  1054. pytest.raises(Exception, self.panel.reindex,
  1055. major_axis=new_major,
  1056. major=new_major)
  1057. # minor
  1058. new_minor = list(self.panel.minor_axis[:2])
  1059. result = self.panel.reindex(minor=new_minor)
  1060. assert_frame_equal(result['ItemB'], ref.reindex(columns=new_minor))
  1061. # raise exception put both major and major_axis
  1062. pytest.raises(Exception, self.panel.reindex,
  1063. minor_axis=new_minor,
  1064. minor=new_minor)
  1065. # this ok
  1066. result = self.panel.reindex()
  1067. assert_panel_equal(result, self.panel)
  1068. assert result is not self.panel
  1069. # with filling
  1070. smaller_major = self.panel.major_axis[::5]
  1071. smaller = self.panel.reindex(major=smaller_major)
  1072. larger = smaller.reindex(major=self.panel.major_axis, method='pad')
  1073. assert_frame_equal(larger.major_xs(self.panel.major_axis[1]),
  1074. smaller.major_xs(smaller_major[0]))
  1075. # don't necessarily copy
  1076. result = self.panel.reindex(
  1077. major=self.panel.major_axis, copy=False)
  1078. assert_panel_equal(result, self.panel)
  1079. assert result is self.panel
  1080. def test_reindex_axis_style(self):
  1081. panel = Panel(np.random.rand(5, 5, 5))
  1082. expected0 = Panel(panel.values).iloc[[0, 1]]
  1083. expected1 = Panel(panel.values).iloc[:, [0, 1]]
  1084. expected2 = Panel(panel.values).iloc[:, :, [0, 1]]
  1085. result = panel.reindex([0, 1], axis=0)
  1086. assert_panel_equal(result, expected0)
  1087. result = panel.reindex([0, 1], axis=1)
  1088. assert_panel_equal(result, expected1)
  1089. result = panel.reindex([0, 1], axis=2)
  1090. assert_panel_equal(result, expected2)
  1091. result = panel.reindex([0, 1], axis=2)
  1092. assert_panel_equal(result, expected2)
  1093. def test_reindex_multi(self):
  1094. # with and without copy full reindexing
  1095. result = self.panel.reindex(
  1096. items=self.panel.items,
  1097. major=self.panel.major_axis,
  1098. minor=self.panel.minor_axis, copy=False)
  1099. assert result.items is self.panel.items
  1100. assert result.major_axis is self.panel.major_axis
  1101. assert result.minor_axis is self.panel.minor_axis
  1102. result = self.panel.reindex(
  1103. items=self.panel.items,
  1104. major=self.panel.major_axis,
  1105. minor=self.panel.minor_axis, copy=False)
  1106. assert_panel_equal(result, self.panel)
  1107. # multi-axis indexing consistency
  1108. # GH 5900
  1109. df = DataFrame(np.random.randn(4, 3))
  1110. p = Panel({'Item1': df})
  1111. expected = Panel({'Item1': df})
  1112. expected['Item2'] = np.nan
  1113. items = ['Item1', 'Item2']
  1114. major_axis = np.arange(4)
  1115. minor_axis = np.arange(3)
  1116. results = []
  1117. results.append(p.reindex(items=items, major_axis=major_axis,
  1118. copy=True))
  1119. results.append(p.reindex(items=items, major_axis=major_axis,
  1120. copy=False))
  1121. results.append(p.reindex(items=items, minor_axis=minor_axis,
  1122. copy=True))
  1123. results.append(p.reindex(items=items, minor_axis=minor_axis,
  1124. copy=False))
  1125. results.append(p.reindex(items=items, major_axis=major_axis,
  1126. minor_axis=minor_axis, copy=True))
  1127. results.append(p.reindex(items=items, major_axis=major_axis,
  1128. minor_axis=minor_axis, copy=False))
  1129. for i, r in enumerate(results):
  1130. assert_panel_equal(expected, r)
  1131. def test_reindex_like(self):
  1132. # reindex_like
  1133. smaller = self.panel.reindex(items=self.panel.items[:-1],
  1134. major=self.panel.major_axis[:-1],
  1135. minor=self.panel.minor_axis[:-1])
  1136. smaller_like = self.panel.reindex_like(smaller)
  1137. assert_panel_equal(smaller, smaller_like)
  1138. def test_take(self):
  1139. # axis == 0
  1140. result = self.panel.take([2, 0, 1], axis=0)
  1141. expected = self.panel.reindex(items=['ItemC', 'ItemA', 'ItemB'])
  1142. assert_panel_equal(result, expected)
  1143. # axis >= 1
  1144. result = self.panel.take([3, 0, 1, 2], axis=2)
  1145. expected = self.panel.reindex(minor=['D', 'A', 'B', 'C'])
  1146. assert_panel_equal(result, expected)
  1147. # neg indices ok
  1148. expected = self.panel.reindex(minor=['D', 'D', 'B', 'C'])
  1149. result = self.panel.take([3, -1, 1, 2], axis=2)
  1150. assert_panel_equal(result, expected)
  1151. pytest.raises(Exception, self.panel.take, [4, 0, 1, 2], axis=2)
  1152. def test_sort_index(self):
  1153. import random
  1154. ritems = list(self.panel.items)
  1155. rmajor = list(self.panel.major_axis)
  1156. rminor = list(self.panel.minor_axis)
  1157. random.shuffle(ritems)
  1158. random.shuffle(rmajor)
  1159. random.shuffle(rminor)
  1160. random_order = self.panel.reindex(items=ritems)
  1161. sorted_panel = random_order.sort_index(axis=0)
  1162. assert_panel_equal(sorted_panel, self.panel)
  1163. # descending
  1164. random_order = self.panel.reindex(items=ritems)
  1165. sorted_panel = random_order.sort_index(axis=0, ascending=False)
  1166. assert_panel_equal(
  1167. sorted_panel,
  1168. self.panel.reindex(items=self.panel.items[::-1]))
  1169. random_order = self.panel.reindex(major=rmajor)
  1170. sorted_panel = random_order.sort_index(axis=1)
  1171. assert_panel_equal(sorted_panel, self.panel)
  1172. random_order = self.panel.reindex(minor=rminor)
  1173. sorted_panel = random_order.sort_index(axis=2)
  1174. assert_panel_equal(sorted_panel, self.panel)
  1175. def test_fillna(self):
  1176. filled = self.panel.fillna(0)
  1177. assert np.isfinite(filled.values).all()
  1178. filled = self.panel.fillna(method='backfill')
  1179. assert_frame_equal(filled['ItemA'],
  1180. self.panel['ItemA'].fillna(method='backfill'))
  1181. panel = self.panel.copy()
  1182. panel['str'] = 'foo'
  1183. filled = panel.fillna(method='backfill')
  1184. assert_frame_equal(filled['ItemA'],
  1185. panel['ItemA'].fillna(method='backfill'))
  1186. empty = self.panel.reindex(items=[])
  1187. filled = empty.fillna(0)
  1188. assert_panel_equal(filled, empty)
  1189. pytest.raises(ValueError, self.panel.fillna)
  1190. pytest.raises(ValueError, self.panel.fillna, 5, method='ffill')
  1191. pytest.raises(TypeError, self.panel.fillna, [1, 2])
  1192. pytest.raises(TypeError, self.panel.fillna, (1, 2))
  1193. # limit not implemented when only value is specified
  1194. p = Panel(np.random.randn(3, 4, 5))
  1195. p.iloc[0:2, 0:2, 0:2] = np.nan
  1196. pytest.raises(NotImplementedError,
  1197. lambda: p.fillna(999, limit=1))
  1198. # Test in place fillNA
  1199. # Expected result
  1200. expected = Panel([[[0, 1], [2, 1]], [[10, 11], [12, 11]]],
  1201. items=['a', 'b'], minor_axis=['x', 'y'],
  1202. dtype=np.float64)
  1203. # method='ffill'
  1204. p1 = Panel([[[0, 1], [2, np.nan]], [[10, 11], [12, np.nan]]],
  1205. items=['a', 'b'], minor_axis=['x', 'y'],
  1206. dtype=np.float64)
  1207. p1.fillna(method='ffill', inplace=True)
  1208. assert_panel_equal(p1, expected)
  1209. # method='bfill'
  1210. p2 = Panel([[[0, np.nan], [2, 1]], [[10, np.nan], [12, 11]]],
  1211. items=['a', 'b'], minor_axis=['x', 'y'],
  1212. dtype=np.float64)
  1213. p2.fillna(method='bfill', inplace=True)
  1214. assert_panel_equal(p2, expected)
  1215. def test_ffill_bfill(self):
  1216. assert_panel_equal(self.panel.ffill(),
  1217. self.panel.fillna(method='ffill'))
  1218. assert_panel_equal(self.panel.bfill(),
  1219. self.panel.fillna(method='bfill'))
  1220. def test_truncate_fillna_bug(self):
  1221. # #1823
  1222. result = self.panel.truncate(before=None, after=None, axis='items')
  1223. # it works!
  1224. result.fillna(value=0.0)
  1225. def test_swapaxes(self):
  1226. result = self.panel.swapaxes('items', 'minor')
  1227. assert result.items is self.panel.minor_axis
  1228. result = self.panel.swapaxes('items', 'major')
  1229. assert result.items is self.panel.major_axis
  1230. result = self.panel.swapaxes('major', 'minor')
  1231. assert result.major_axis is self.panel.minor_axis
  1232. panel = self.panel.copy()
  1233. result = panel.swapaxes('major', 'minor')
  1234. panel.values[0, 0, 1] = np.nan
  1235. expected = panel.swapaxes('major', 'minor')
  1236. assert_panel_equal(result, expected)
  1237. # this should also work
  1238. result = self.panel.swapaxes(0, 1)
  1239. assert result.items is self.panel.major_axis
  1240. # this works, but return a copy
  1241. result = self.panel.swapaxes('items', 'items')
  1242. assert_panel_equal(self.panel, result)
  1243. assert id(self.panel) != id(result)
  1244. def test_transpose(self):
  1245. result = self.panel.transpose('minor', 'major', 'items')
  1246. expected = self.panel.swapaxes('items', 'minor')
  1247. assert_panel_equal(result, expected)
  1248. # test kwargs
  1249. result = self.panel.transpose(items='minor', major='major',
  1250. minor='items')
  1251. expected = self.panel.swapaxes('items', 'minor')
  1252. assert_panel_equal(result, expected)
  1253. # text mixture of args
  1254. result = self.panel.transpose(
  1255. 'minor', major='major', minor='items')
  1256. expected = self.panel.swapaxes('items', 'minor')
  1257. assert_panel_equal(result, expected)
  1258. result = self.panel.transpose('minor',
  1259. 'major',
  1260. minor='items')
  1261. expected = self.panel.swapaxes('items', 'minor')
  1262. assert_panel_equal(result, expected)
  1263. # duplicate axes
  1264. with pytest.raises(TypeError,
  1265. match='not enough/duplicate arguments'):
  1266. self.panel.transpose('minor', maj='major', minor='items')
  1267. with pytest.raises(ValueError,
  1268. match='repeated axis in transpose'):
  1269. self.panel.transpose('minor', 'major', major='minor',
  1270. minor='items')
  1271. result = self.panel.transpose(2, 1, 0)
  1272. assert_panel_equal(result, expected)
  1273. result = self.panel.transpose('minor', 'items', 'major')
  1274. expected = self.panel.swapaxes('items', 'minor')
  1275. expected = expected.swapaxes('major', 'minor')
  1276. assert_panel_equal(result, expected)
  1277. result = self.panel.transpose(2, 0, 1)
  1278. assert_panel_equal(result, expected)
  1279. pytest.raises(ValueError, self.panel.transpose, 0, 0, 1)
  1280. def test_transpose_copy(self):
  1281. panel = self.panel.copy()
  1282. result = panel.transpose(2, 0, 1, copy=True)
  1283. expected = panel.swapaxes('items', 'minor')
  1284. expected = expected.swapaxes('major', 'minor')
  1285. assert_panel_equal(result, expected)
  1286. panel.values[0, 1, 1] = np.nan
  1287. assert notna(result.values[1, 0, 1])
  1288. def test_to_frame(self):
  1289. # filtered
  1290. filtered = self.panel.to_frame()
  1291. expected = self.panel.to_frame().dropna(how='any')
  1292. assert_frame_equal(filtered, expected)
  1293. # unfiltered
  1294. unfiltered = self.panel.to_frame(filter_observations=False)
  1295. assert_panel_equal(unfiltered.to_panel(), self.panel)
  1296. # names
  1297. assert unfiltered.index.names == ('major', 'minor')
  1298. # unsorted, round trip
  1299. df = self.panel.to_frame(filter_observations=False)
  1300. unsorted = df.take(np.random.permutation(len(df)))
  1301. pan = unsorted.to_panel()
  1302. assert_panel_equal(pan, self.panel)
  1303. # preserve original index names
  1304. df = DataFrame(np.random.randn(6, 2),
  1305. index=[['a', 'a', 'b', 'b', 'c', 'c'],
  1306. [0, 1, 0, 1, 0, 1]],
  1307. columns=['one', 'two'])
  1308. df.index.names = ['foo', 'bar']
  1309. df.columns.name = 'baz'
  1310. rdf = df.to_panel().to_frame()
  1311. assert rdf.index.names == df.index.names
  1312. assert rdf.columns.names == df.columns.names
  1313. def test_to_frame_mixed(self):
  1314. panel = self.panel.fillna(0)
  1315. panel['str'] = 'foo'
  1316. panel['bool'] = panel['ItemA'] > 0
  1317. lp = panel.to_frame()
  1318. wp = lp.to_panel()
  1319. assert wp['bool'].values.dtype == np.bool_
  1320. # Previously, this was mutating the underlying
  1321. # index and changing its name
  1322. assert_frame_equal(wp['bool'], panel['bool'], check_names=False)
  1323. # GH 8704
  1324. # with categorical
  1325. df = panel.to_frame()
  1326. df['category'] = df['str'].astype('category')
  1327. # to_panel
  1328. # TODO: this converts back to object
  1329. p = df.to_panel()
  1330. expected = panel.copy()
  1331. expected['category'] = 'foo'
  1332. assert_panel_equal(p, expected)
  1333. def test_to_frame_multi_major(self):
  1334. idx = MultiIndex.from_tuples(
  1335. [(1, 'one'), (1, 'two'), (2, 'one'), (2, 'two')])
  1336. df = DataFrame([[1, 'a', 1], [2, 'b', 1],
  1337. [3, 'c', 1], [4, 'd', 1]],
  1338. columns=['A', 'B', 'C'], index=idx)
  1339. wp = Panel({'i1': df, 'i2': df})
  1340. expected_idx = MultiIndex.from_tuples(
  1341. [
  1342. (1, 'one', 'A'), (1, 'one', 'B'),
  1343. (1, 'one', 'C'), (1, 'two', 'A'),
  1344. (1, 'two', 'B'), (1, 'two', 'C'),
  1345. (2, 'one', 'A'), (2, 'one', 'B'),
  1346. (2, 'one', 'C'), (2, 'two', 'A'),
  1347. (2, 'two', 'B'), (2, 'two', 'C')
  1348. ],
  1349. names=[None, None, 'minor'])
  1350. expected = DataFrame({'i1': [1, 'a', 1, 2, 'b', 1, 3,
  1351. 'c', 1, 4, 'd', 1],
  1352. 'i2': [1, 'a', 1, 2, 'b',
  1353. 1, 3, 'c', 1, 4, 'd', 1]},
  1354. index=expected_idx)
  1355. result = wp.to_frame()
  1356. assert_frame_equal(result, expected)
  1357. wp.iloc[0, 0].iloc[0] = np.nan # BUG on setting. GH #5773
  1358. result = wp.to_frame()
  1359. assert_frame_equal(result, expected[1:])
  1360. idx = MultiIndex.from_tuples(
  1361. [(1, 'two'), (1, 'one'), (2, 'one'), (np.nan, 'two')])
  1362. df = DataFrame([[1, 'a', 1], [2, 'b', 1],
  1363. [3, 'c', 1], [4, 'd', 1]],
  1364. columns=['A', 'B', 'C'], index=idx)
  1365. wp = Panel({'i1': df, 'i2': df})
  1366. ex_idx = MultiIndex.from_tuples([(1, 'two', 'A'), (1, 'two', 'B'),
  1367. (1, 'two', 'C'),
  1368. (1, 'one', 'A'),
  1369. (1, 'one', 'B'),
  1370. (1, 'one', 'C'),
  1371. (2, 'one', 'A'),
  1372. (2, 'one', 'B'),
  1373. (2, 'one', 'C'),
  1374. (np.nan, 'two', 'A'),
  1375. (np.nan, 'two', 'B'),
  1376. (np.nan, 'two', 'C')],
  1377. names=[None, None, 'minor'])
  1378. expected.index = ex_idx
  1379. result = wp.to_frame()
  1380. assert_frame_equal(result, expected)
  1381. def test_to_frame_multi_major_minor(self):
  1382. cols = MultiIndex(levels=[['C_A', 'C_B'], ['C_1', 'C_2']],
  1383. codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
  1384. idx = MultiIndex.from_tuples([(1, 'one'), (1, 'two'), (2, 'one'), (
  1385. 2, 'two'), (3, 'three'), (4, 'four')])
  1386. df = DataFrame([[1, 2, 11, 12], [3, 4, 13, 14],
  1387. ['a', 'b', 'w', 'x'],
  1388. ['c', 'd', 'y', 'z'], [-1, -2, -3, -4],
  1389. [-5, -6, -7, -8]], columns=cols, index=idx)
  1390. wp = Panel({'i1': df, 'i2': df})
  1391. exp_idx = MultiIndex.from_tuples(
  1392. [(1, 'one', 'C_A', 'C_1'), (1, 'one', 'C_A', 'C_2'),
  1393. (1, 'one', 'C_B', 'C_1'), (1, 'one', 'C_B', 'C_2'),
  1394. (1, 'two', 'C_A', 'C_1'), (1, 'two', 'C_A', 'C_2'),
  1395. (1, 'two', 'C_B', 'C_1'), (1, 'two', 'C_B', 'C_2'),
  1396. (2, 'one', 'C_A', 'C_1'), (2, 'one', 'C_A', 'C_2'),
  1397. (2, 'one', 'C_B', 'C_1'), (2, 'one', 'C_B', 'C_2'),
  1398. (2, 'two', 'C_A', 'C_1'), (2, 'two', 'C_A', 'C_2'),
  1399. (2, 'two', 'C_B', 'C_1'), (2, 'two', 'C_B', 'C_2'),
  1400. (3, 'three', 'C_A', 'C_1'), (3, 'three', 'C_A', 'C_2'),
  1401. (3, 'three', 'C_B', 'C_1'), (3, 'three', 'C_B', 'C_2'),
  1402. (4, 'four', 'C_A', 'C_1'), (4, 'four', 'C_A', 'C_2'),
  1403. (4, 'four', 'C_B', 'C_1'), (4, 'four', 'C_B', 'C_2')],
  1404. names=[None, None, None, None])
  1405. exp_val = [[1, 1], [2, 2], [11, 11], [12, 12],
  1406. [3, 3], [4, 4],
  1407. [13, 13], [14, 14], ['a', 'a'],
  1408. ['b', 'b'], ['w', 'w'],
  1409. ['x', 'x'], ['c', 'c'], ['d', 'd'], [
  1410. 'y', 'y'], ['z', 'z'],
  1411. [-1, -1], [-2, -2], [-3, -3], [-4, -4],
  1412. [-5, -5], [-6, -6],
  1413. [-7, -7], [-8, -8]]
  1414. result = wp.to_frame()
  1415. expected = DataFrame(exp_val, columns=['i1', 'i2'], index=exp_idx)
  1416. assert_frame_equal(result, expected)
  1417. def test_to_frame_multi_drop_level(self):
  1418. idx = MultiIndex.from_tuples([(1, 'one'), (2, 'one'), (2, 'two')])
  1419. df = DataFrame({'A': [np.nan, 1, 2]}, index=idx)
  1420. wp = Panel({'i1': df, 'i2': df})
  1421. result = wp.to_frame()
  1422. exp_idx = MultiIndex.from_tuples(
  1423. [(2, 'one', 'A'), (2, 'two', 'A')],
  1424. names=[None, None, 'minor'])
  1425. expected = DataFrame({'i1': [1., 2], 'i2': [1., 2]}, index=exp_idx)
  1426. assert_frame_equal(result, expected)
  1427. def test_to_panel_na_handling(self):
  1428. df = DataFrame(np.random.randint(0, 10, size=20).reshape((10, 2)),
  1429. index=[[0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
  1430. [0, 1, 2, 3, 4, 5, 2, 3, 4, 5]])
  1431. panel = df.to_panel()
  1432. assert isna(panel[0].loc[1, [0, 1]]).all()
  1433. def test_to_panel_duplicates(self):
  1434. # #2441
  1435. df = DataFrame({'a': [0, 0, 1], 'b': [1, 1, 1], 'c': [1, 2, 3]})
  1436. idf = df.set_index(['a', 'b'])
  1437. with pytest.raises(ValueError, match='non-uniquely indexed'):
  1438. idf.to_panel()
  1439. def test_panel_dups(self):
  1440. # GH 4960
  1441. # duplicates in an index
  1442. # items
  1443. data = np.random.randn(5, 100, 5)
  1444. no_dup_panel = Panel(data, items=list("ABCDE"))
  1445. panel = Panel(data, items=list("AACDE"))
  1446. expected = no_dup_panel['A']
  1447. result = panel.iloc[0]
  1448. assert_frame_equal(result, expected)
  1449. expected = no_dup_panel['E']
  1450. result = panel.loc['E']
  1451. assert_frame_equal(result, expected)
  1452. expected = no_dup_panel.loc[['A', 'B']]
  1453. expected.items = ['A', 'A']
  1454. result = panel.loc['A']
  1455. assert_panel_equal(result, expected)
  1456. # major
  1457. data = np.random.randn(5, 5, 5)
  1458. no_dup_panel = Panel(data, major_axis=list("ABCDE"))
  1459. panel = Panel(data, major_axis=list("AACDE"))
  1460. expected = no_dup_panel.loc[:, 'A']
  1461. result = panel.iloc[:, 0]
  1462. assert_frame_equal(result, expected)
  1463. expected = no_dup_panel.loc[:, 'E']
  1464. result = panel.loc[:, 'E']
  1465. assert_frame_equal(result, expected)
  1466. expected = no_dup_panel.loc[:, ['A', 'B']]
  1467. expected.major_axis = ['A', 'A']
  1468. result = panel.loc[:, 'A']
  1469. assert_panel_equal(result, expected)
  1470. # minor
  1471. data = np.random.randn(5, 100, 5)
  1472. no_dup_panel = Panel(data, minor_axis=list("ABCDE"))
  1473. panel = Panel(data, minor_axis=list("AACDE"))
  1474. expected = no_dup_panel.loc[:, :, 'A']
  1475. result = panel.iloc[:, :, 0]
  1476. assert_frame_equal(result, expected)
  1477. expected = no_dup_panel.loc[:, :, 'E']
  1478. result = panel.loc[:, :, 'E']
  1479. assert_frame_equal(result, expected)
  1480. expected = no_dup_panel.loc[:, :, ['A', 'B']]
  1481. expected.minor_axis = ['A', 'A']
  1482. result = panel.loc[:, :, 'A']
  1483. assert_panel_equal(result, expected)
  1484. def test_filter(self):
  1485. pass
  1486. def test_compound(self):
  1487. compounded = self.panel.compound()
  1488. assert_series_equal(compounded['ItemA'],
  1489. (1 + self.panel['ItemA']).product(0) - 1,
  1490. check_names=False)
  1491. def test_shift(self):
  1492. # major
  1493. idx = self.panel.major_axis[0]
  1494. idx_lag = self.panel.major_axis[1]
  1495. shifted = self.panel.shift(1)
  1496. assert_frame_equal(self.panel.major_xs(idx),
  1497. shifted.major_xs(idx_lag))
  1498. # minor
  1499. idx = self.panel.minor_axis[0]
  1500. idx_lag = self.panel.minor_axis[1]
  1501. shifted = self.panel.shift(1, axis='minor')
  1502. assert_frame_equal(self.panel.minor_xs(idx),
  1503. shifted.minor_xs(idx_lag))
  1504. # items
  1505. idx = self.panel.items[0]
  1506. idx_lag = self.panel.items[1]
  1507. shifted = self.panel.shift(1, axis='items')
  1508. assert_frame_equal(self.panel[idx], shifted[idx_lag])
  1509. # negative numbers, #2164
  1510. result = self.panel.shift(-1)
  1511. expected = Panel({i: f.shift(-1)[:-1]
  1512. for i, f in self.panel.iteritems()})
  1513. assert_panel_equal(result, expected)
  1514. # mixed dtypes #6959
  1515. data = [('item ' + ch, makeMixedDataFrame())
  1516. for ch in list('abcde')]
  1517. data = dict(data)
  1518. mixed_panel = Panel.from_dict(data, orient='minor')
  1519. shifted = mixed_panel.shift(1)
  1520. assert_series_equal(mixed_panel.dtypes, shifted.dtypes)
  1521. def test_tshift(self):
  1522. # PeriodIndex
  1523. ps = tm.makePeriodPanel()
  1524. shifted = ps.tshift(1)
  1525. unshifted = shifted.tshift(-1)
  1526. assert_panel_equal(unshifted, ps)
  1527. shifted2 = ps.tshift(freq='B')
  1528. assert_panel_equal(shifted, shifted2)
  1529. shifted3 = ps.tshift(freq=BDay())
  1530. assert_panel_equal(shifted, shifted3)
  1531. with pytest.raises(ValueError, match='does not match'):
  1532. ps.tshift(freq='M')
  1533. # DatetimeIndex
  1534. panel = make_test_panel()
  1535. shifted = panel.tshift(1)
  1536. unshifted = shifted.tshift(-1)
  1537. assert_panel_equal(panel, unshifted)
  1538. shifted2 = panel.tshift(freq=panel.major_axis.freq)
  1539. assert_panel_equal(shifted, shifted2)
  1540. inferred_ts = Panel(panel.values, items=panel.items,
  1541. major_axis=Index(np.asarray(panel.major_axis)),
  1542. minor_axis=panel.minor_axis)
  1543. shifted = inferred_ts.tshift(1)
  1544. unshifted = shifted.tshift(-1)
  1545. assert_panel_equal(shifted, panel.tshift(1))
  1546. assert_panel_equal(unshifted, inferred_ts)
  1547. no_freq = panel.iloc[:, [0, 5, 7], :]
  1548. pytest.raises(ValueError, no_freq.tshift)
  1549. def test_pct_change(self):
  1550. df1 = DataFrame({'c1': [1, 2, 5], 'c2': [3, 4, 6]})
  1551. df2 = df1 + 1
  1552. df3 = DataFrame({'c1': [3, 4, 7], 'c2': [5, 6, 8]})
  1553. wp = Panel({'i1': df1, 'i2': df2, 'i3': df3})
  1554. # major, 1
  1555. result = wp.pct_change() # axis='major'
  1556. expected = Panel({'i1': df1.pct_change(),
  1557. 'i2': df2.pct_change(),
  1558. 'i3': df3.pct_change()})
  1559. assert_panel_equal(result, expected)
  1560. result = wp.pct_change(axis=1)
  1561. assert_panel_equal(result, expected)
  1562. # major, 2
  1563. result = wp.pct_change(periods=2)
  1564. expected = Panel({'i1': df1.pct_change(2),
  1565. 'i2': df2.pct_change(2),
  1566. 'i3': df3.pct_change(2)})
  1567. assert_panel_equal(result, expected)
  1568. # minor, 1
  1569. result = wp.pct_change(axis='minor')
  1570. expected = Panel({'i1': df1.pct_change(axis=1),
  1571. 'i2': df2.pct_change(axis=1),
  1572. 'i3': df3.pct_change(axis=1)})
  1573. assert_panel_equal(result, expected)
  1574. result = wp.pct_change(axis=2)
  1575. assert_panel_equal(result, expected)
  1576. # minor, 2
  1577. result = wp.pct_change(periods=2, axis='minor')
  1578. expected = Panel({'i1': df1.pct_change(periods=2, axis=1),
  1579. 'i2': df2.pct_change(periods=2, axis=1),
  1580. 'i3': df3.pct_change(periods=2, axis=1)})
  1581. assert_panel_equal(result, expected)
  1582. # items, 1
  1583. result = wp.pct_change(axis='items')
  1584. expected = Panel(
  1585. {'i1': DataFrame({'c1': [np.nan, np.nan, np.nan],
  1586. 'c2': [np.nan, np.nan, np.nan]}),
  1587. 'i2': DataFrame({'c1': [1, 0.5, .2],
  1588. 'c2': [1. / 3, 0.25, 1. / 6]}),
  1589. 'i3': DataFrame({'c1': [.5, 1. / 3, 1. / 6],
  1590. 'c2': [.25, .2, 1. / 7]})})
  1591. assert_panel_equal(result, expected)
  1592. result = wp.pct_change(axis=0)
  1593. assert_panel_equal(result, expected)
  1594. # items, 2
  1595. result = wp.pct_change(periods=2, axis='items')
  1596. expected = Panel(
  1597. {'i1': DataFrame({'c1': [np.nan, np.nan, np.nan],
  1598. 'c2': [np.nan, np.nan, np.nan]}),
  1599. 'i2': DataFrame({'c1': [np.nan, np.nan, np.nan],
  1600. 'c2': [np.nan, np.nan, np.nan]}),
  1601. 'i3': DataFrame({'c1': [2, 1, .4],
  1602. 'c2': [2. / 3, .5, 1. / 3]})})
  1603. assert_panel_equal(result, expected)
  1604. def test_round(self):
  1605. values = [[[-3.2, 2.2], [0, -4.8213], [3.123, 123.12],
  1606. [-1566.213, 88.88], [-12, 94.5]],
  1607. [[-5.82, 3.5], [6.21, -73.272], [-9.087, 23.12],
  1608. [272.212, -99.99], [23, -76.5]]]
  1609. evalues = [[[float(np.around(i)) for i in j] for j in k]
  1610. for k in values]
  1611. p = Panel(values, items=['Item1', 'Item2'],
  1612. major_axis=date_range('1/1/2000', periods=5),
  1613. minor_axis=['A', 'B'])
  1614. expected = Panel(evalues, items=['Item1', 'Item2'],
  1615. major_axis=date_range('1/1/2000', periods=5),
  1616. minor_axis=['A', 'B'])
  1617. result = p.round()
  1618. assert_panel_equal(expected, result)
  1619. def test_numpy_round(self):
  1620. values = [[[-3.2, 2.2], [0, -4.8213], [3.123, 123.12],
  1621. [-1566.213, 88.88], [-12, 94.5]],
  1622. [[-5.82, 3.5], [6.21, -73.272], [-9.087, 23.12],
  1623. [272.212, -99.99], [23, -76.5]]]
  1624. evalues = [[[float(np.around(i)) for i in j] for j in k]
  1625. for k in values]
  1626. p = Panel(values, items=['Item1', 'Item2'],
  1627. major_axis=date_range('1/1/2000', periods=5),
  1628. minor_axis=['A', 'B'])
  1629. expected = Panel(evalues, items=['Item1', 'Item2'],
  1630. major_axis=date_range('1/1/2000', periods=5),
  1631. minor_axis=['A', 'B'])
  1632. result = np.round(p)
  1633. assert_panel_equal(expected, result)
  1634. msg = "the 'out' parameter is not supported"
  1635. with pytest.raises(ValueError, match=msg):
  1636. np.round(p, out=p)
  1637. # removing Panel before NumPy enforces, so just ignore
  1638. @pytest.mark.filterwarnings("ignore:Using a non-tuple:FutureWarning")
  1639. def test_multiindex_get(self):
  1640. ind = MultiIndex.from_tuples(
  1641. [('a', 1), ('a', 2), ('b', 1), ('b', 2)],
  1642. names=['first', 'second'])
  1643. wp = Panel(np.random.random((4, 5, 5)),
  1644. items=ind,
  1645. major_axis=np.arange(5),
  1646. minor_axis=np.arange(5))
  1647. f1 = wp['a']
  1648. f2 = wp.loc['a']
  1649. assert_panel_equal(f1, f2)
  1650. assert (f1.items == [1, 2]).all()
  1651. assert (f2.items == [1, 2]).all()
  1652. MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)],
  1653. names=['first', 'second'])
  1654. @pytest.mark.filterwarnings("ignore:Using a non-tuple:FutureWarning")
  1655. def test_multiindex_blocks(self):
  1656. ind = MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)],
  1657. names=['first', 'second'])
  1658. wp = Panel(self.panel._data)
  1659. wp.items = ind
  1660. f1 = wp['a']
  1661. assert (f1.items == [1, 2]).all()
  1662. f1 = wp[('b', 1)]
  1663. assert (f1.columns == ['A', 'B', 'C', 'D']).all()
  1664. def test_repr_empty(self):
  1665. empty = Panel()
  1666. repr(empty)
  1667. # ignore warning from us, because removing panel
  1668. @pytest.mark.filterwarnings("ignore:Using:FutureWarning")
  1669. def test_rename(self):
  1670. mapper = {'ItemA': 'foo', 'ItemB': 'bar', 'ItemC': 'baz'}
  1671. renamed = self.panel.rename(items=mapper)
  1672. exp = Index(['foo', 'bar', 'baz'])
  1673. tm.assert_index_equal(renamed.items, exp)
  1674. renamed = self.panel.rename(minor_axis=str.lower)
  1675. exp = Index(['a', 'b', 'c', 'd'])
  1676. tm.assert_index_equal(renamed.minor_axis, exp)
  1677. # don't copy
  1678. renamed_nocopy = self.panel.rename(items=mapper, copy=False)
  1679. renamed_nocopy['foo'] = 3.
  1680. assert (self.panel['ItemA'].values == 3).all()
  1681. def test_get_attr(self):
  1682. assert_frame_equal(self.panel['ItemA'], self.panel.ItemA)
  1683. # specific cases from #3440
  1684. self.panel['a'] = self.panel['ItemA']
  1685. assert_frame_equal(self.panel['a'], self.panel.a)
  1686. self.panel['i'] = self.panel['ItemA']
  1687. assert_frame_equal(self.panel['i'], self.panel.i)
  1688. def test_from_frame_level1_unsorted(self):
  1689. tuples = [('MSFT', 3), ('MSFT', 2), ('AAPL', 2), ('AAPL', 1),
  1690. ('MSFT', 1)]
  1691. midx = MultiIndex.from_tuples(tuples)
  1692. df = DataFrame(np.random.rand(5, 4), index=midx)
  1693. p = df.to_panel()
  1694. assert_frame_equal(p.minor_xs(2), df.xs(2, level=1).sort_index())
  1695. def test_to_excel(self):
  1696. try:
  1697. import xlwt # noqa
  1698. import xlrd # noqa
  1699. import openpyxl # noqa
  1700. from pandas.io.excel import ExcelFile
  1701. except ImportError:
  1702. pytest.skip("need xlwt xlrd openpyxl")
  1703. for ext in ['xls', 'xlsx']:
  1704. with ensure_clean('__tmp__.' + ext) as path:
  1705. self.panel.to_excel(path)
  1706. try:
  1707. reader = ExcelFile(path)
  1708. except ImportError:
  1709. pytest.skip("need xlwt xlrd openpyxl")
  1710. for item, df in self.panel.iteritems():
  1711. recdf = reader.parse(str(item), index_col=0)
  1712. assert_frame_equal(df, recdf)
  1713. def test_to_excel_xlsxwriter(self):
  1714. try:
  1715. import xlrd # noqa
  1716. import xlsxwriter # noqa
  1717. from pandas.io.excel import ExcelFile
  1718. except ImportError:
  1719. pytest.skip("Requires xlrd and xlsxwriter. Skipping test.")
  1720. with ensure_clean('__tmp__.xlsx') as path:
  1721. self.panel.to_excel(path, engine='xlsxwriter')
  1722. try:
  1723. reader = ExcelFile(path)
  1724. except ImportError as e:
  1725. pytest.skip("cannot write excel file: %s" % e)
  1726. for item, df in self.panel.iteritems():
  1727. recdf = reader.parse(str(item), index_col=0)
  1728. assert_frame_equal(df, recdf)
  1729. @pytest.mark.filterwarnings("ignore:'.reindex:FutureWarning")
  1730. def test_dropna(self):
  1731. p = Panel(np.random.randn(4, 5, 6), major_axis=list('abcde'))
  1732. p.loc[:, ['b', 'd'], 0] = np.nan
  1733. result = p.dropna(axis=1)
  1734. exp = p.loc[:, ['a', 'c', 'e'], :]
  1735. assert_panel_equal(result, exp)
  1736. inp = p.copy()
  1737. inp.dropna(axis=1, inplace=True)
  1738. assert_panel_equal(inp, exp)
  1739. result = p.dropna(axis=1, how='all')
  1740. assert_panel_equal(result, p)
  1741. p.loc[:, ['b', 'd'], :] = np.nan
  1742. result = p.dropna(axis=1, how='all')
  1743. exp = p.loc[:, ['a', 'c', 'e'], :]
  1744. assert_panel_equal(result, exp)
  1745. p = Panel(np.random.randn(4, 5, 6), items=list('abcd'))
  1746. p.loc[['b'], :, 0] = np.nan
  1747. result = p.dropna()
  1748. exp = p.loc[['a', 'c', 'd']]
  1749. assert_panel_equal(result, exp)
  1750. result = p.dropna(how='all')
  1751. assert_panel_equal(result, p)
  1752. p.loc['b'] = np.nan
  1753. result = p.dropna(how='all')
  1754. exp = p.loc[['a', 'c', 'd']]
  1755. assert_panel_equal(result, exp)
  1756. def test_drop(self):
  1757. df = DataFrame({"A": [1, 2], "B": [3, 4]})
  1758. panel = Panel({"One": df, "Two": df})
  1759. def check_drop(drop_val, axis_number, aliases, expected):
  1760. try:
  1761. actual = panel.drop(drop_val, axis=axis_number)
  1762. assert_panel_equal(actual, expected)
  1763. for alias in aliases:
  1764. actual = panel.drop(drop_val, axis=alias)
  1765. assert_panel_equal(actual, expected)
  1766. except AssertionError:
  1767. pprint_thing("Failed with axis_number %d and aliases: %s" %
  1768. (axis_number, aliases))
  1769. raise
  1770. # Items
  1771. expected = Panel({"One": df})
  1772. check_drop('Two', 0, ['items'], expected)
  1773. pytest.raises(KeyError, panel.drop, 'Three')
  1774. # errors = 'ignore'
  1775. dropped = panel.drop('Three', errors='ignore')
  1776. assert_panel_equal(dropped, panel)
  1777. dropped = panel.drop(['Two', 'Three'], errors='ignore')
  1778. expected = Panel({"One": df})
  1779. assert_panel_equal(dropped, expected)
  1780. # Major
  1781. exp_df = DataFrame({"A": [2], "B": [4]}, index=[1])
  1782. expected = Panel({"One": exp_df, "Two": exp_df})
  1783. check_drop(0, 1, ['major_axis', 'major'], expected)
  1784. exp_df = DataFrame({"A": [1], "B": [3]}, index=[0])
  1785. expected = Panel({"One": exp_df, "Two": exp_df})
  1786. check_drop([1], 1, ['major_axis', 'major'], expected)
  1787. # Minor
  1788. exp_df = df[['B']]
  1789. expected = Panel({"One": exp_df, "Two": exp_df})
  1790. check_drop(["A"], 2, ['minor_axis', 'minor'], expected)
  1791. exp_df = df[['A']]
  1792. expected = Panel({"One": exp_df, "Two": exp_df})
  1793. check_drop("B", 2, ['minor_axis', 'minor'], expected)
  1794. def test_update(self):
  1795. pan = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1796. [1.5, np.nan, 3.],
  1797. [1.5, np.nan, 3.]],
  1798. [[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1799. [1.5, np.nan, 3.],
  1800. [1.5, np.nan, 3.]]])
  1801. other = Panel(
  1802. [[[3.6, 2., np.nan], [np.nan, np.nan, 7]]], items=[1])
  1803. pan.update(other)
  1804. expected = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1805. [1.5, np.nan, 3.], [1.5, np.nan, 3.]],
  1806. [[3.6, 2., 3], [1.5, np.nan, 7],
  1807. [1.5, np.nan, 3.],
  1808. [1.5, np.nan, 3.]]])
  1809. assert_panel_equal(pan, expected)
  1810. def test_update_from_dict(self):
  1811. pan = Panel({'one': DataFrame([[1.5, np.nan, 3],
  1812. [1.5, np.nan, 3],
  1813. [1.5, np.nan, 3.],
  1814. [1.5, np.nan, 3.]]),
  1815. 'two': DataFrame([[1.5, np.nan, 3.],
  1816. [1.5, np.nan, 3.],
  1817. [1.5, np.nan, 3.],
  1818. [1.5, np.nan, 3.]])})
  1819. other = {'two': DataFrame(
  1820. [[3.6, 2., np.nan], [np.nan, np.nan, 7]])}
  1821. pan.update(other)
  1822. expected = Panel(
  1823. {'one': DataFrame([[1.5, np.nan, 3.],
  1824. [1.5, np.nan, 3.],
  1825. [1.5, np.nan, 3.],
  1826. [1.5, np.nan, 3.]]),
  1827. 'two': DataFrame([[3.6, 2., 3],
  1828. [1.5, np.nan, 7],
  1829. [1.5, np.nan, 3.],
  1830. [1.5, np.nan, 3.]])
  1831. }
  1832. )
  1833. assert_panel_equal(pan, expected)
  1834. def test_update_nooverwrite(self):
  1835. pan = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1836. [1.5, np.nan, 3.],
  1837. [1.5, np.nan, 3.]],
  1838. [[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1839. [1.5, np.nan, 3.],
  1840. [1.5, np.nan, 3.]]])
  1841. other = Panel(
  1842. [[[3.6, 2., np.nan], [np.nan, np.nan, 7]]], items=[1])
  1843. pan.update(other, overwrite=False)
  1844. expected = Panel([[[1.5, np.nan, 3], [1.5, np.nan, 3],
  1845. [1.5, np.nan, 3.], [1.5, np.nan, 3.]],
  1846. [[1.5, 2., 3.], [1.5, np.nan, 3.],
  1847. [1.5, np.nan, 3.],
  1848. [1.5, np.nan, 3.]]])
  1849. assert_panel_equal(pan, expected)
  1850. def test_update_filtered(self):
  1851. pan = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1852. [1.5, np.nan, 3.],
  1853. [1.5, np.nan, 3.]],
  1854. [[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1855. [1.5, np.nan, 3.],
  1856. [1.5, np.nan, 3.]]])
  1857. other = Panel(
  1858. [[[3.6, 2., np.nan], [np.nan, np.nan, 7]]], items=[1])
  1859. pan.update(other, filter_func=lambda x: x > 2)
  1860. expected = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1861. [1.5, np.nan, 3.], [1.5, np.nan, 3.]],
  1862. [[1.5, np.nan, 3], [1.5, np.nan, 7],
  1863. [1.5, np.nan, 3.], [1.5, np.nan, 3.]]])
  1864. assert_panel_equal(pan, expected)
  1865. @pytest.mark.parametrize('bad_kwarg, exception, msg', [
  1866. # errors must be 'ignore' or 'raise'
  1867. ({'errors': 'something'}, ValueError, 'The parameter errors must.*'),
  1868. ({'join': 'inner'}, NotImplementedError, 'Only left join is supported')
  1869. ])
  1870. def test_update_raise_bad_parameter(self, bad_kwarg, exception, msg):
  1871. pan = Panel([[[1.5, np.nan, 3.]]])
  1872. with pytest.raises(exception, match=msg):
  1873. pan.update(pan, **bad_kwarg)
  1874. def test_update_raise_on_overlap(self):
  1875. pan = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1876. [1.5, np.nan, 3.],
  1877. [1.5, np.nan, 3.]],
  1878. [[1.5, np.nan, 3.], [1.5, np.nan, 3.],
  1879. [1.5, np.nan, 3.],
  1880. [1.5, np.nan, 3.]]])
  1881. with pytest.raises(ValueError, match='Data overlaps'):
  1882. pan.update(pan, errors='raise')
  1883. @pytest.mark.parametrize('raise_conflict', [True, False])
  1884. def test_update_deprecation(self, raise_conflict):
  1885. pan = Panel([[[1.5, np.nan, 3.]]])
  1886. other = Panel([[[]]])
  1887. with tm.assert_produces_warning(FutureWarning):
  1888. pan.update(other, raise_conflict=raise_conflict)
  1889. def test_all_any(self):
  1890. assert (self.panel.all(axis=0).values == nanall(
  1891. self.panel, axis=0)).all()
  1892. assert (self.panel.all(axis=1).values == nanall(
  1893. self.panel, axis=1).T).all()
  1894. assert (self.panel.all(axis=2).values == nanall(
  1895. self.panel, axis=2).T).all()
  1896. assert (self.panel.any(axis=0).values == nanany(
  1897. self.panel, axis=0)).all()
  1898. assert (self.panel.any(axis=1).values == nanany(
  1899. self.panel, axis=1).T).all()
  1900. assert (self.panel.any(axis=2).values == nanany(
  1901. self.panel, axis=2).T).all()
  1902. def test_all_any_unhandled(self):
  1903. pytest.raises(NotImplementedError, self.panel.all, bool_only=True)
  1904. pytest.raises(NotImplementedError, self.panel.any, bool_only=True)
  1905. # GH issue 15960
  1906. def test_sort_values(self):
  1907. pytest.raises(NotImplementedError, self.panel.sort_values)
  1908. pytest.raises(NotImplementedError, self.panel.sort_values, 'ItemA')
  1909. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  1910. class TestPanelFrame(object):
  1911. """
  1912. Check that conversions to and from Panel to DataFrame work.
  1913. """
  1914. def setup_method(self, method):
  1915. panel = make_test_panel()
  1916. self.panel = panel.to_frame()
  1917. self.unfiltered_panel = panel.to_frame(filter_observations=False)
  1918. def test_ops_differently_indexed(self):
  1919. # trying to set non-identically indexed panel
  1920. wp = self.panel.to_panel()
  1921. wp2 = wp.reindex(major=wp.major_axis[:-1])
  1922. lp2 = wp2.to_frame()
  1923. result = self.panel + lp2
  1924. assert_frame_equal(result.reindex(lp2.index), lp2 * 2)
  1925. # careful, mutation
  1926. self.panel['foo'] = lp2['ItemA']
  1927. assert_series_equal(self.panel['foo'].reindex(lp2.index),
  1928. lp2['ItemA'],
  1929. check_names=False)
  1930. def test_ops_scalar(self):
  1931. result = self.panel.mul(2)
  1932. expected = DataFrame.__mul__(self.panel, 2)
  1933. assert_frame_equal(result, expected)
  1934. def test_combineFrame(self):
  1935. wp = self.panel.to_panel()
  1936. result = self.panel.add(wp['ItemA'].stack(), axis=0)
  1937. assert_frame_equal(result.to_panel()['ItemA'], wp['ItemA'] * 2)
  1938. def test_combinePanel(self):
  1939. wp = self.panel.to_panel()
  1940. result = self.panel.add(self.panel)
  1941. wide_result = result.to_panel()
  1942. assert_frame_equal(wp['ItemA'] * 2, wide_result['ItemA'])
  1943. # one item
  1944. result = self.panel.add(self.panel.filter(['ItemA']))
  1945. def test_combine_scalar(self):
  1946. result = self.panel.mul(2)
  1947. expected = DataFrame(self.panel._data) * 2
  1948. assert_frame_equal(result, expected)
  1949. def test_combine_series(self):
  1950. s = self.panel['ItemA'][:10]
  1951. result = self.panel.add(s, axis=0)
  1952. expected = DataFrame.add(self.panel, s, axis=0)
  1953. assert_frame_equal(result, expected)
  1954. s = self.panel.iloc[5]
  1955. result = self.panel + s
  1956. expected = DataFrame.add(self.panel, s, axis=1)
  1957. assert_frame_equal(result, expected)
  1958. def test_operators(self):
  1959. wp = self.panel.to_panel()
  1960. result = (self.panel + 1).to_panel()
  1961. assert_frame_equal(wp['ItemA'] + 1, result['ItemA'])
  1962. def test_arith_flex_panel(self):
  1963. ops = ['add', 'sub', 'mul', 'div',
  1964. 'truediv', 'pow', 'floordiv', 'mod']
  1965. if not compat.PY3:
  1966. aliases = {}
  1967. else:
  1968. aliases = {'div': 'truediv'}
  1969. self.panel = self.panel.to_panel()
  1970. for n in [np.random.randint(-50, -1), np.random.randint(1, 50), 0]:
  1971. for op in ops:
  1972. alias = aliases.get(op, op)
  1973. f = getattr(operator, alias)
  1974. exp = f(self.panel, n)
  1975. result = getattr(self.panel, op)(n)
  1976. assert_panel_equal(result, exp, check_panel_type=True)
  1977. # rops
  1978. r_f = lambda x, y: f(y, x)
  1979. exp = r_f(self.panel, n)
  1980. result = getattr(self.panel, 'r' + op)(n)
  1981. assert_panel_equal(result, exp)
  1982. def test_sort(self):
  1983. def is_sorted(arr):
  1984. return (arr[1:] > arr[:-1]).any()
  1985. sorted_minor = self.panel.sort_index(level=1)
  1986. assert is_sorted(sorted_minor.index.codes[1])
  1987. sorted_major = sorted_minor.sort_index(level=0)
  1988. assert is_sorted(sorted_major.index.codes[0])
  1989. def test_to_string(self):
  1990. buf = StringIO()
  1991. self.panel.to_string(buf)
  1992. def test_to_sparse(self):
  1993. if isinstance(self.panel, Panel):
  1994. msg = 'sparsifying is not supported'
  1995. with pytest.raises(NotImplementedError, match=msg):
  1996. self.panel.to_sparse
  1997. def test_truncate(self):
  1998. dates = self.panel.index.levels[0]
  1999. start, end = dates[1], dates[5]
  2000. trunced = self.panel.truncate(start, end).to_panel()
  2001. expected = self.panel.to_panel()['ItemA'].truncate(start, end)
  2002. # TODO truncate drops index.names
  2003. assert_frame_equal(trunced['ItemA'], expected, check_names=False)
  2004. trunced = self.panel.truncate(before=start).to_panel()
  2005. expected = self.panel.to_panel()['ItemA'].truncate(before=start)
  2006. # TODO truncate drops index.names
  2007. assert_frame_equal(trunced['ItemA'], expected, check_names=False)
  2008. trunced = self.panel.truncate(after=end).to_panel()
  2009. expected = self.panel.to_panel()['ItemA'].truncate(after=end)
  2010. # TODO truncate drops index.names
  2011. assert_frame_equal(trunced['ItemA'], expected, check_names=False)
  2012. # truncate on dates that aren't in there
  2013. wp = self.panel.to_panel()
  2014. new_index = wp.major_axis[::5]
  2015. wp2 = wp.reindex(major=new_index)
  2016. lp2 = wp2.to_frame()
  2017. lp_trunc = lp2.truncate(wp.major_axis[2], wp.major_axis[-2])
  2018. wp_trunc = wp2.truncate(wp.major_axis[2], wp.major_axis[-2])
  2019. assert_panel_equal(wp_trunc, lp_trunc.to_panel())
  2020. # throw proper exception
  2021. pytest.raises(Exception, lp2.truncate, wp.major_axis[-2],
  2022. wp.major_axis[2])
  2023. def test_axis_dummies(self):
  2024. from pandas.core.reshape.reshape import make_axis_dummies
  2025. minor_dummies = make_axis_dummies(self.panel, 'minor').astype(np.uint8)
  2026. assert len(minor_dummies.columns) == len(self.panel.index.levels[1])
  2027. major_dummies = make_axis_dummies(self.panel, 'major').astype(np.uint8)
  2028. assert len(major_dummies.columns) == len(self.panel.index.levels[0])
  2029. mapping = {'A': 'one', 'B': 'one', 'C': 'two', 'D': 'two'}
  2030. transformed = make_axis_dummies(self.panel, 'minor',
  2031. transform=mapping.get).astype(np.uint8)
  2032. assert len(transformed.columns) == 2
  2033. tm.assert_index_equal(transformed.columns, Index(['one', 'two']))
  2034. # TODO: test correctness
  2035. def test_get_dummies(self):
  2036. from pandas.core.reshape.reshape import get_dummies, make_axis_dummies
  2037. self.panel['Label'] = self.panel.index.codes[1]
  2038. minor_dummies = make_axis_dummies(self.panel, 'minor').astype(np.uint8)
  2039. dummies = get_dummies(self.panel['Label'])
  2040. tm.assert_numpy_array_equal(dummies.values, minor_dummies.values)
  2041. def test_mean(self):
  2042. means = self.panel.mean(level='minor')
  2043. # test versus Panel version
  2044. wide_means = self.panel.to_panel().mean('major')
  2045. assert_frame_equal(means, wide_means)
  2046. def test_sum(self):
  2047. sums = self.panel.sum(level='minor')
  2048. # test versus Panel version
  2049. wide_sums = self.panel.to_panel().sum('major')
  2050. assert_frame_equal(sums, wide_sums)
  2051. def test_count(self):
  2052. index = self.panel.index
  2053. major_count = self.panel.count(level=0)['ItemA']
  2054. level_codes = index.codes[0]
  2055. for i, idx in enumerate(index.levels[0]):
  2056. assert major_count[i] == (level_codes == i).sum()
  2057. minor_count = self.panel.count(level=1)['ItemA']
  2058. level_codes = index.codes[1]
  2059. for i, idx in enumerate(index.levels[1]):
  2060. assert minor_count[i] == (level_codes == i).sum()
  2061. def test_join(self):
  2062. lp1 = self.panel.filter(['ItemA', 'ItemB'])
  2063. lp2 = self.panel.filter(['ItemC'])
  2064. joined = lp1.join(lp2)
  2065. assert len(joined.columns) == 3
  2066. pytest.raises(Exception, lp1.join,
  2067. self.panel.filter(['ItemB', 'ItemC']))
  2068. def test_panel_index():
  2069. index = panelm.panel_index([1, 2, 3, 4], [1, 2, 3])
  2070. expected = MultiIndex.from_arrays([np.tile([1, 2, 3, 4], 3),
  2071. np.repeat([1, 2, 3], 4)],
  2072. names=['time', 'panel'])
  2073. tm.assert_index_equal(index, expected)
  2074. @pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
  2075. def test_panel_np_all():
  2076. wp = Panel({"A": DataFrame({'b': [1, 2]})})
  2077. result = np.all(wp)
  2078. assert result == np.bool_(True)