From 003609a90cae73b408abf5b490a26ded0b4d6c19 Mon Sep 17 00:00:00 2001 From: LJ Date: Thu, 27 Dec 2018 18:44:25 +0200 Subject: [PATCH 1/9] DOC: fix flake8 issue in groupby.rst (#24363) --- doc/source/groupby.rst | 34 ++++++++++++++++++++++++---------- setup.cfg | 1 - 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/doc/source/groupby.rst b/doc/source/groupby.rst index 76481b8cc765a..a37aa2644a805 100644 --- a/doc/source/groupby.rst +++ b/doc/source/groupby.rst @@ -66,12 +66,21 @@ pandas objects can be split on any of their axes. The abstract definition of grouping is to provide a mapping of labels to group names. To create a GroupBy object (more on what the GroupBy object is later), you may do the following: -.. code-block:: python +.. ipython:: python + + df = pd.DataFrame([('bird', 'Falconiformes', 389.0), + ('bird', 'Psittaciformes', 24.0), + ('mammal', 'Carnivora', 80.2), + ('mammal', 'Primates', np.nan), + ('mammal', 'Carnivora', 58)], + index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'], + columns=('class', 'order', 'max_speed')) + df - # default is axis=0 - >>> grouped = obj.groupby(key) - >>> grouped = obj.groupby(key, axis=1) - >>> grouped = obj.groupby([key1, key2]) + # default is axis=0 + grouped = df.groupby('class') + grouped = df.groupby('order', axis='columns') + grouped = df.groupby(['class', 'order']) The mapping can be specified many different ways: @@ -239,7 +248,7 @@ the length of the ``groups`` dict, so it is largely just a convenience: .. ipython:: @verbatim - In [1]: gb. + In [1]: gb. # noqa: E225, E999 gb.agg gb.boxplot gb.cummin gb.describe gb.filter gb.get_group gb.height gb.last gb.median gb.ngroups gb.plot gb.rank gb.std gb.transform gb.aggregate gb.count gb.cumprod gb.dtype gb.first gb.groups gb.hist gb.max gb.min gb.nth gb.prod gb.resample gb.sum gb.var gb.apply gb.cummax gb.cumsum gb.fillna gb.gender gb.head gb.indices gb.mean gb.name gb.ohlc gb.quantile gb.size gb.tail gb.weight @@ -1300,12 +1309,17 @@ Now, to find prices per store/product, we can simply do: Piping can also be expressive when you want to deliver a grouped object to some arbitrary function, for example: -.. code-block:: python +.. ipython:: python + + def mean(groupby): + return groupby.mean() - df.groupby(['Store', 'Product']).pipe(report_func) + df.groupby(['Store', 'Product']).pipe(mean) -where ``report_func`` takes a GroupBy object and creates a report -from that. +where ``mean`` takes a GroupBy object and finds the mean of the Revenue and Quantity +columns repectively for each Store-Product combination. The ``mean`` function can +be any function that takes in a GroupBy object; the ``.pipe`` will pass the GroupBy +object as a parameter into the function you specify. Examples -------- diff --git a/setup.cfg b/setup.cfg index 380100df774c1..c199567737531 100644 --- a/setup.cfg +++ b/setup.cfg @@ -53,7 +53,6 @@ exclude = doc/source/basics.rst doc/source/contributing_docstring.rst doc/source/enhancingperf.rst - doc/source/groupby.rst [yapf] From 74db5b5583768605b4c0c551334d07fc72ba065c Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 27 Dec 2018 16:46:28 +0000 Subject: [PATCH 2/9] DOC: Adding offsets to API ref (#24446) --- doc/source/api.rst | 1406 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1361 insertions(+), 45 deletions(-) diff --git a/doc/source/api.rst b/doc/source/api.rst index d80c73d4a7c1c..44a7d6f408030 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -2139,54 +2139,1370 @@ Date Offsets .. currentmodule:: pandas.tseries.offsets +DateOffset +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + DateOffset + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + DateOffset.freqstr + DateOffset.kwds + DateOffset.name + DateOffset.nanos + DateOffset.normalize + DateOffset.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + DateOffset.apply + DateOffset.copy + DateOffset.isAnchored + DateOffset.onOffset + +BusinessDay +~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessDay + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessDay.freqstr + BusinessDay.kwds + BusinessDay.name + BusinessDay.nanos + BusinessDay.normalize + BusinessDay.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessDay.apply + BusinessDay.apply_index + BusinessDay.copy + BusinessDay.isAnchored + BusinessDay.onOffset + +BusinessHour +~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessHour + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessHour.freqstr + BusinessHour.kwds + BusinessHour.name + BusinessHour.nanos + BusinessHour.normalize + BusinessHour.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessHour.apply + BusinessHour.copy + BusinessHour.isAnchored + BusinessHour.onOffset + +CustomBusinessDay +~~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessDay + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessDay.freqstr + CustomBusinessDay.kwds + CustomBusinessDay.name + CustomBusinessDay.nanos + CustomBusinessDay.normalize + CustomBusinessDay.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessDay.apply + CustomBusinessDay.copy + CustomBusinessDay.isAnchored + CustomBusinessDay.onOffset + +CustomBusinessHour +~~~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessHour + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessHour.freqstr + CustomBusinessHour.kwds + CustomBusinessHour.name + CustomBusinessHour.nanos + CustomBusinessHour.normalize + CustomBusinessHour.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessHour.apply + CustomBusinessHour.copy + CustomBusinessHour.isAnchored + CustomBusinessHour.onOffset + +MonthOffset +~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthOffset + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthOffset.freqstr + MonthOffset.kwds + MonthOffset.name + MonthOffset.nanos + MonthOffset.normalize + MonthOffset.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthOffset.apply + MonthOffset.apply_index + MonthOffset.copy + MonthOffset.isAnchored + MonthOffset.onOffset + +MonthEnd +~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthEnd.freqstr + MonthEnd.kwds + MonthEnd.name + MonthEnd.nanos + MonthEnd.normalize + MonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthEnd.apply + MonthEnd.apply_index + MonthEnd.copy + MonthEnd.isAnchored + MonthEnd.onOffset + +MonthBegin +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthBegin.freqstr + MonthBegin.kwds + MonthBegin.name + MonthBegin.nanos + MonthBegin.normalize + MonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + MonthBegin.apply + MonthBegin.apply_index + MonthBegin.copy + MonthBegin.isAnchored + MonthBegin.onOffset + +BusinessMonthEnd +~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthEnd.freqstr + BusinessMonthEnd.kwds + BusinessMonthEnd.name + BusinessMonthEnd.nanos + BusinessMonthEnd.normalize + BusinessMonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthEnd.apply + BusinessMonthEnd.apply_index + BusinessMonthEnd.copy + BusinessMonthEnd.isAnchored + BusinessMonthEnd.onOffset + +BusinessMonthBegin +~~~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthBegin.freqstr + BusinessMonthBegin.kwds + BusinessMonthBegin.name + BusinessMonthBegin.nanos + BusinessMonthBegin.normalize + BusinessMonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BusinessMonthBegin.apply + BusinessMonthBegin.apply_index + BusinessMonthBegin.copy + BusinessMonthBegin.isAnchored + BusinessMonthBegin.onOffset + +CustomBusinessMonthEnd +~~~~~~~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthEnd.freqstr + CustomBusinessMonthEnd.kwds + CustomBusinessMonthEnd.m_offset + CustomBusinessMonthEnd.name + CustomBusinessMonthEnd.nanos + CustomBusinessMonthEnd.normalize + CustomBusinessMonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthEnd.apply + CustomBusinessMonthEnd.copy + CustomBusinessMonthEnd.isAnchored + CustomBusinessMonthEnd.onOffset + +CustomBusinessMonthBegin +~~~~~~~~~~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthBegin.freqstr + CustomBusinessMonthBegin.kwds + CustomBusinessMonthBegin.m_offset + CustomBusinessMonthBegin.name + CustomBusinessMonthBegin.nanos + CustomBusinessMonthBegin.normalize + CustomBusinessMonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CustomBusinessMonthBegin.apply + CustomBusinessMonthBegin.copy + CustomBusinessMonthBegin.isAnchored + CustomBusinessMonthBegin.onOffset + +SemiMonthOffset +~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthOffset + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthOffset.freqstr + SemiMonthOffset.kwds + SemiMonthOffset.name + SemiMonthOffset.nanos + SemiMonthOffset.normalize + SemiMonthOffset.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthOffset.apply + SemiMonthOffset.apply_index + SemiMonthOffset.copy + SemiMonthOffset.isAnchored + SemiMonthOffset.onOffset + +SemiMonthEnd +~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthEnd.freqstr + SemiMonthEnd.kwds + SemiMonthEnd.name + SemiMonthEnd.nanos + SemiMonthEnd.normalize + SemiMonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthEnd.apply + SemiMonthEnd.apply_index + SemiMonthEnd.copy + SemiMonthEnd.isAnchored + SemiMonthEnd.onOffset + +SemiMonthBegin +~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthBegin.freqstr + SemiMonthBegin.kwds + SemiMonthBegin.name + SemiMonthBegin.nanos + SemiMonthBegin.normalize + SemiMonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + SemiMonthBegin.apply + SemiMonthBegin.apply_index + SemiMonthBegin.copy + SemiMonthBegin.isAnchored + SemiMonthBegin.onOffset + +Week +~~~~ +.. autosummary:: + :toctree: generated/ + + Week + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Week.freqstr + Week.kwds + Week.name + Week.nanos + Week.normalize + Week.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Week.apply + Week.apply_index + Week.copy + Week.isAnchored + Week.onOffset + +WeekOfMonth +~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + WeekOfMonth + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + WeekOfMonth.freqstr + WeekOfMonth.kwds + WeekOfMonth.name + WeekOfMonth.nanos + WeekOfMonth.normalize + WeekOfMonth.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + WeekOfMonth.apply + WeekOfMonth.copy + WeekOfMonth.isAnchored + WeekOfMonth.onOffset + +LastWeekOfMonth +~~~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + LastWeekOfMonth + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + LastWeekOfMonth.freqstr + LastWeekOfMonth.kwds + LastWeekOfMonth.name + LastWeekOfMonth.nanos + LastWeekOfMonth.normalize + LastWeekOfMonth.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + LastWeekOfMonth.apply + LastWeekOfMonth.copy + LastWeekOfMonth.isAnchored + LastWeekOfMonth.onOffset + +QuarterOffset +~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterOffset + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterOffset.freqstr + QuarterOffset.kwds + QuarterOffset.name + QuarterOffset.nanos + QuarterOffset.normalize + QuarterOffset.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterOffset.apply + QuarterOffset.apply_index + QuarterOffset.copy + QuarterOffset.isAnchored + QuarterOffset.onOffset + +BQuarterEnd +~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterEnd.freqstr + BQuarterEnd.kwds + BQuarterEnd.name + BQuarterEnd.nanos + BQuarterEnd.normalize + BQuarterEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterEnd.apply + BQuarterEnd.apply_index + BQuarterEnd.copy + BQuarterEnd.isAnchored + BQuarterEnd.onOffset + +BQuarterBegin +~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterBegin.freqstr + BQuarterBegin.kwds + BQuarterBegin.name + BQuarterBegin.nanos + BQuarterBegin.normalize + BQuarterBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BQuarterBegin.apply + BQuarterBegin.apply_index + BQuarterBegin.copy + BQuarterBegin.isAnchored + BQuarterBegin.onOffset + +QuarterEnd +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterEnd.freqstr + QuarterEnd.kwds + QuarterEnd.name + QuarterEnd.nanos + QuarterEnd.normalize + QuarterEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterEnd.apply + QuarterEnd.apply_index + QuarterEnd.copy + QuarterEnd.isAnchored + QuarterEnd.onOffset + +QuarterBegin +~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterBegin.freqstr + QuarterBegin.kwds + QuarterBegin.name + QuarterBegin.nanos + QuarterBegin.normalize + QuarterBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + QuarterBegin.apply + QuarterBegin.apply_index + QuarterBegin.copy + QuarterBegin.isAnchored + QuarterBegin.onOffset + +YearOffset +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearOffset + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearOffset.freqstr + YearOffset.kwds + YearOffset.name + YearOffset.nanos + YearOffset.normalize + YearOffset.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearOffset.apply + YearOffset.apply_index + YearOffset.copy + YearOffset.isAnchored + YearOffset.onOffset + +BYearEnd +~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearEnd.freqstr + BYearEnd.kwds + BYearEnd.name + BYearEnd.nanos + BYearEnd.normalize + BYearEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearEnd.apply + BYearEnd.apply_index + BYearEnd.copy + BYearEnd.isAnchored + BYearEnd.onOffset + +BYearBegin +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearBegin.freqstr + BYearBegin.kwds + BYearBegin.name + BYearBegin.nanos + BYearBegin.normalize + BYearBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BYearBegin.apply + BYearBegin.apply_index + BYearBegin.copy + BYearBegin.isAnchored + BYearBegin.onOffset + +YearEnd +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearEnd.freqstr + YearEnd.kwds + YearEnd.name + YearEnd.nanos + YearEnd.normalize + YearEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearEnd.apply + YearEnd.apply_index + YearEnd.copy + YearEnd.isAnchored + YearEnd.onOffset + +YearBegin +~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearBegin.freqstr + YearBegin.kwds + YearBegin.name + YearBegin.nanos + YearBegin.normalize + YearBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + YearBegin.apply + YearBegin.apply_index + YearBegin.copy + YearBegin.isAnchored + YearBegin.onOffset + +FY5253 +~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253 + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253.freqstr + FY5253.kwds + FY5253.name + FY5253.nanos + FY5253.normalize + FY5253.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253.apply + FY5253.copy + FY5253.get_rule_code_suffix + FY5253.get_year_end + FY5253.isAnchored + FY5253.onOffset + +FY5253Quarter +~~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253Quarter + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253Quarter.freqstr + FY5253Quarter.kwds + FY5253Quarter.name + FY5253Quarter.nanos + FY5253Quarter.normalize + FY5253Quarter.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + FY5253Quarter.apply + FY5253Quarter.copy + FY5253Quarter.get_weeks + FY5253Quarter.isAnchored + FY5253Quarter.onOffset + FY5253Quarter.year_has_extra_week + +Easter +~~~~~~ +.. autosummary:: + :toctree: generated/ + + Easter + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Easter.freqstr + Easter.kwds + Easter.name + Easter.nanos + Easter.normalize + Easter.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Easter.apply + Easter.copy + Easter.isAnchored + Easter.onOffset + +Tick +~~~~ +.. autosummary:: + :toctree: generated/ + + Tick + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Tick.delta + Tick.freqstr + Tick.kwds + Tick.name + Tick.nanos + Tick.normalize + Tick.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Tick.copy + Tick.isAnchored + Tick.onOffset + +Day +~~~ +.. autosummary:: + :toctree: generated/ + + Day + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Day.delta + Day.freqstr + Day.kwds + Day.name + Day.nanos + Day.normalize + Day.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Day.copy + Day.isAnchored + Day.onOffset + +Hour +~~~~ +.. autosummary:: + :toctree: generated/ + + Hour + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Hour.delta + Hour.freqstr + Hour.kwds + Hour.name + Hour.nanos + Hour.normalize + Hour.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Hour.copy + Hour.isAnchored + Hour.onOffset + +Minute +~~~~~~ +.. autosummary:: + :toctree: generated/ + + Minute + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Minute.delta + Minute.freqstr + Minute.kwds + Minute.name + Minute.nanos + Minute.normalize + Minute.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Minute.copy + Minute.isAnchored + Minute.onOffset + +Second +~~~~~~ +.. autosummary:: + :toctree: generated/ + + Second + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Second.delta + Second.freqstr + Second.kwds + Second.name + Second.nanos + Second.normalize + Second.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Second.copy + Second.isAnchored + Second.onOffset + +Milli +~~~~~ +.. autosummary:: + :toctree: generated/ + + Milli + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Milli.delta + Milli.freqstr + Milli.kwds + Milli.name + Milli.nanos + Milli.normalize + Milli.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Milli.copy + Milli.isAnchored + Milli.onOffset + +Micro +~~~~~ +.. autosummary:: + :toctree: generated/ + + Micro + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Micro.delta + Micro.freqstr + Micro.kwds + Micro.name + Micro.nanos + Micro.normalize + Micro.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Micro.copy + Micro.isAnchored + Micro.onOffset + +Nano +~~~~ +.. autosummary:: + :toctree: generated/ + + Nano + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Nano.delta + Nano.freqstr + Nano.kwds + Nano.name + Nano.nanos + Nano.normalize + Nano.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + Nano.copy + Nano.isAnchored + Nano.onOffset + +BDay +~~~~ +.. autosummary:: + :toctree: generated/ + + BDay + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BDay.base + BDay.freqstr + BDay.kwds + BDay.name + BDay.nanos + BDay.normalize + BDay.offset + BDay.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BDay.apply + BDay.apply_index + BDay.copy + BDay.isAnchored + BDay.onOffset + BDay.rollback + BDay.rollforward + +BMonthEnd +~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthEnd.base + BMonthEnd.freqstr + BMonthEnd.kwds + BMonthEnd.name + BMonthEnd.nanos + BMonthEnd.normalize + BMonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthEnd.apply + BMonthEnd.apply_index + BMonthEnd.copy + BMonthEnd.isAnchored + BMonthEnd.onOffset + BMonthEnd.rollback + BMonthEnd.rollforward + +BMonthBegin +~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthBegin.base + BMonthBegin.freqstr + BMonthBegin.kwds + BMonthBegin.name + BMonthBegin.nanos + BMonthBegin.normalize + BMonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + BMonthBegin.apply + BMonthBegin.apply_index + BMonthBegin.copy + BMonthBegin.isAnchored + BMonthBegin.onOffset + BMonthBegin.rollback + BMonthBegin.rollforward + +CBMonthEnd +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthEnd + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthEnd.base + CBMonthEnd.cbday_roll + CBMonthEnd.freqstr + CBMonthEnd.kwds + CBMonthEnd.m_offset + CBMonthEnd.month_roll + CBMonthEnd.name + CBMonthEnd.nanos + CBMonthEnd.normalize + CBMonthEnd.offset + CBMonthEnd.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthEnd.apply + CBMonthEnd.apply_index + CBMonthEnd.copy + CBMonthEnd.isAnchored + CBMonthEnd.onOffset + CBMonthEnd.rollback + CBMonthEnd.rollforward + +CBMonthBegin +~~~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthBegin + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthBegin.base + CBMonthBegin.cbday_roll + CBMonthBegin.freqstr + CBMonthBegin.kwds + CBMonthBegin.m_offset + CBMonthBegin.month_roll + CBMonthBegin.name + CBMonthBegin.nanos + CBMonthBegin.normalize + CBMonthBegin.offset + CBMonthBegin.rule_code + +Methods +~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CBMonthBegin.apply + CBMonthBegin.apply_index + CBMonthBegin.copy + CBMonthBegin.isAnchored + CBMonthBegin.onOffset + CBMonthBegin.rollback + CBMonthBegin.rollforward + +CDay +~~~~ +.. autosummary:: + :toctree: generated/ + + CDay + +Properties +~~~~~~~~~~ +.. autosummary:: + :toctree: generated/ + + CDay.base + CDay.freqstr + CDay.kwds + CDay.name + CDay.nanos + CDay.normalize + CDay.offset + CDay.rule_code + +Methods +~~~~~~~ .. autosummary:: :toctree: generated/ - DateOffset - BusinessDay - BusinessHour - CustomBusinessDay - CustomBusinessHour - MonthOffset - MonthEnd - MonthBegin - BusinessMonthEnd - BusinessMonthBegin - CustomBusinessMonthEnd - CustomBusinessMonthBegin - SemiMonthOffset - SemiMonthEnd - SemiMonthBegin - Week - WeekOfMonth - LastWeekOfMonth - QuarterOffset - BQuarterEnd - BQuarterBegin - QuarterEnd - QuarterBegin - YearOffset - BYearEnd - BYearBegin - YearEnd - YearBegin - FY5253 - FY5253Quarter - Easter - Tick - Day - Hour - Minute - Second - Milli - Micro - Nano - BDay - BMonthEnd - BMonthBegin - CBMonthEnd - CBMonthBegin - CDay + CDay.apply + CDay.apply_index + CDay.copy + CDay.isAnchored + CDay.onOffset + CDay.rollback + CDay.rollforward .. _api.frequencies: From 98b3e4ca141f4008eab7e10e49586389d86db42d Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 27 Dec 2018 16:46:42 +0000 Subject: [PATCH 3/9] DOC: Adding links to offset classes in timeseries.rst (#24448) --- doc/source/timeseries.rst | 68 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/doc/source/timeseries.rst b/doc/source/timeseries.rst index 349827f1e8807..59e8fa58fd9cf 100644 --- a/doc/source/timeseries.rst +++ b/doc/source/timeseries.rst @@ -855,40 +855,40 @@ into ``freq`` keyword arguments. The available date offsets and associated frequ :header: "Date Offset", "Frequency String", "Description" :widths: 15, 15, 65 - ``DateOffset``, None, "Generic offset class, defaults to 1 calendar day" - ``BDay`` or ``BusinessDay``, ``'B'``,"business day (weekday)" - ``CDay`` or ``CustomBusinessDay``, ``'C'``, "custom business day" - ``Week``, ``'W'``, "one week, optionally anchored on a day of the week" - ``WeekOfMonth``, ``'WOM'``, "the x-th day of the y-th week of each month" - ``LastWeekOfMonth``, ``'LWOM'``, "the x-th day of the last week of each month" - ``MonthEnd``, ``'M'``, "calendar month end" - ``MonthBegin``, ``'MS'``, "calendar month begin" - ``BMonthEnd`` or ``BusinessMonthEnd``, ``'BM'``, "business month end" - ``BMonthBegin`` or ``BusinessMonthBegin``, ``'BMS'``, "business month begin" - ``CBMonthEnd`` or ``CustomBusinessMonthEnd``, ``'CBM'``, "custom business month end" - ``CBMonthBegin`` or ``CustomBusinessMonthBegin``, ``'CBMS'``, "custom business month begin" - ``SemiMonthEnd``, ``'SM'``, "15th (or other day_of_month) and calendar month end" - ``SemiMonthBegin``, ``'SMS'``, "15th (or other day_of_month) and calendar month begin" - ``QuarterEnd``, ``'Q'``, "calendar quarter end" - ``QuarterBegin``, ``'QS'``, "calendar quarter begin" - ``BQuarterEnd``, ``'BQ``, "business quarter end" - ``BQuarterBegin``, ``'BQS'``, "business quarter begin" - ``FY5253Quarter``, ``'REQ'``, "retail (aka 52-53 week) quarter" - ``YearEnd``, ``'A'``, "calendar year end" - ``YearBegin``, ``'AS'`` or ``'BYS'``,"calendar year begin" - ``BYearEnd``, ``'BA'``, "business year end" - ``BYearBegin``, ``'BAS'``, "business year begin" - ``FY5253``, ``'RE'``, "retail (aka 52-53 week) year" - ``Easter``, None, "Easter holiday" - ``BusinessHour``, ``'BH'``, "business hour" - ``CustomBusinessHour``, ``'CBH'``, "custom business hour" - ``Day``, ``'D'``, "one absolute day" - ``Hour``, ``'H'``, "one hour" - ``Minute``, ``'T'`` or ``'min'``,"one minute" - ``Second``, ``'S'``, "one second" - ``Milli``, ``'L'`` or ``'ms'``, "one millisecond" - ``Micro``, ``'U'`` or ``'us'``, "one microsecond" - ``Nano``, ``'N'``, "one nanosecond" + :class:`~pandas.tseries.offsets.DateOffset`, None, "Generic offset class, defaults to 1 calendar day" + :class:`~pandas.tseries.offsets.BDay` or :class:`~pandas.tseries.offsets.BusinessDay`, ``'B'``,"business day (weekday)" + :class:`~pandas.tseries.offsets.CDay` or :class:`~pandas.tseries.offsets.CustomBusinessDay`, ``'C'``, "custom business day" + :class:`~pandas.tseries.offsets.Week`, ``'W'``, "one week, optionally anchored on a day of the week" + :class:`~pandas.tseries.offsets.WeekOfMonth`, ``'WOM'``, "the x-th day of the y-th week of each month" + :class:`~pandas.tseries.offsets.LastWeekOfMonth`, ``'LWOM'``, "the x-th day of the last week of each month" + :class:`~pandas.tseries.offsets.MonthEnd`, ``'M'``, "calendar month end" + :class:`~pandas.tseries.offsets.MonthBegin`, ``'MS'``, "calendar month begin" + :class:`~pandas.tseries.offsets.BMonthEnd` or :class:`~pandas.tseries.offsets.BusinessMonthEnd`, ``'BM'``, "business month end" + :class:`~pandas.tseries.offsets.BMonthBegin` or :class:`~pandas.tseries.offsets.BusinessMonthBegin`, ``'BMS'``, "business month begin" + :class:`~pandas.tseries.offsets.CBMonthEnd` or :class:`~pandas.tseries.offsets.CustomBusinessMonthEnd`, ``'CBM'``, "custom business month end" + :class:`~pandas.tseries.offsets.CBMonthBegin` or :class:`~pandas.tseries.offsets.CustomBusinessMonthBegin`, ``'CBMS'``, "custom business month begin" + :class:`~pandas.tseries.offsets.SemiMonthEnd`, ``'SM'``, "15th (or other day_of_month) and calendar month end" + :class:`~pandas.tseries.offsets.SemiMonthBegin`, ``'SMS'``, "15th (or other day_of_month) and calendar month begin" + :class:`~pandas.tseries.offsets.QuarterEnd`, ``'Q'``, "calendar quarter end" + :class:`~pandas.tseries.offsets.QuarterBegin`, ``'QS'``, "calendar quarter begin" + :class:`~pandas.tseries.offsets.BQuarterEnd`, ``'BQ``, "business quarter end" + :class:`~pandas.tseries.offsets.BQuarterBegin`, ``'BQS'``, "business quarter begin" + :class:`~pandas.tseries.offsets.FY5253Quarter`, ``'REQ'``, "retail (aka 52-53 week) quarter" + :class:`~pandas.tseries.offsets.YearEnd`, ``'A'``, "calendar year end" + :class:`~pandas.tseries.offsets.YearBegin`, ``'AS'`` or ``'BYS'``,"calendar year begin" + :class:`~pandas.tseries.offsets.BYearEnd`, ``'BA'``, "business year end" + :class:`~pandas.tseries.offsets.BYearBegin`, ``'BAS'``, "business year begin" + :class:`~pandas.tseries.offsets.FY5253`, ``'RE'``, "retail (aka 52-53 week) year" + :class:`~pandas.tseries.offsets.Easter`, None, "Easter holiday" + :class:`~pandas.tseries.offsets.BusinessHour`, ``'BH'``, "business hour" + :class:`~pandas.tseries.offsets.CustomBusinessHour`, ``'CBH'``, "custom business hour" + :class:`~pandas.tseries.offsets.Day`, ``'D'``, "one absolute day" + :class:`~pandas.tseries.offsets.Hour`, ``'H'``, "one hour" + :class:`~pandas.tseries.offsets.Minute`, ``'T'`` or ``'min'``,"one minute" + :class:`~pandas.tseries.offsets.Second`, ``'S'``, "one second" + :class:`~pandas.tseries.offsets.Milli`, ``'L'`` or ``'ms'``, "one millisecond" + :class:`~pandas.tseries.offsets.Micro`, ``'U'`` or ``'us'``, "one microsecond" + :class:`~pandas.tseries.offsets.Nano`, ``'N'``, "one nanosecond" ``DateOffsets`` additionally have :meth:`rollforward` and :meth:`rollback` methods for moving a date forward or backward respectively to a valid offset From 289285ef3f3713ad7267ab2040dea0f2b3d6ed7a Mon Sep 17 00:00:00 2001 From: Benjamin Rowell Date: Thu, 27 Dec 2018 16:47:23 +0000 Subject: [PATCH 4/9] DOC: Add dateutil to intersphinx #24437 (#24443) --- doc/source/conf.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 2bef64cce5c35..452f0ffa77b80 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -371,13 +371,14 @@ intersphinx_mapping = { - 'statsmodels': ('http://www.statsmodels.org/devel/', None), + 'dateutil': ("https://dateutil.readthedocs.io/en/latest/", None), 'matplotlib': ('https://matplotlib.org/', None), + 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'pandas-gbq': ('https://pandas-gbq.readthedocs.io/en/latest/', None), + 'py': ('https://pylib.readthedocs.io/en/latest/', None), 'python': ('https://docs.python.org/3/', None), - 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None), - 'py': ('https://pylib.readthedocs.io/en/latest/', None) + 'statsmodels': ('http://www.statsmodels.org/devel/', None), } import glob autosummary_generate = glob.glob("*.rst") From 7e64d9c99b14f6596bf1b72e25a7cb451d0159f1 Mon Sep 17 00:00:00 2001 From: Daniel Saxton Date: Thu, 27 Dec 2018 11:49:33 -0500 Subject: [PATCH 5/9] DOC: Fix minor typo in whatsnew (#24453) --- doc/source/whatsnew/v0.24.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index df6c131489726..d8a204abcd93e 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -371,7 +371,7 @@ Other Enhancements - :meth:`read_excel()` now accepts ``usecols`` as a list of column names or callable (:issue:`18273`) - :meth:`MultiIndex.to_flat_index` has been added to flatten multiple levels into a single-level :class:`Index` object. - :meth:`DataFrame.to_stata` and :class:`pandas.io.stata.StataWriter117` can write mixed sting columns to Stata strl format (:issue:`23633`) -- :meth:`DataFrame.between_time` and :meth:`DataFrame.at_time` have gained the an ``axis`` parameter (:issue:`8839`) +- :meth:`DataFrame.between_time` and :meth:`DataFrame.at_time` have gained the ``axis`` parameter (:issue:`8839`) - The ``scatter_matrix``, ``andrews_curves``, ``parallel_coordinates``, ``lag_plot``, ``autocorrelation_plot``, ``bootstrap_plot``, and ``radviz`` plots from the ``pandas.plotting`` module are now accessible from calling :meth:`DataFrame.plot` (:issue:`11978`) - :class:`IntervalIndex` has gained the :attr:`~IntervalIndex.is_overlapping` attribute to indicate if the ``IntervalIndex`` contains any overlapping intervals (:issue:`23309`) From 3086e0a170934d87b01fa910f371002a55fd07b9 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Fri, 28 Dec 2018 08:26:22 +1300 Subject: [PATCH 6/9] BUG: Infer compression by default in read_fwf() (#22200) Closes gh-22199. --- doc/source/whatsnew/v0.24.0.rst | 1 + pandas/io/parsers.py | 2 +- pandas/tests/io/parser/test_read_fwf.py | 14 ++++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index d8a204abcd93e..7960984699baf 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1536,6 +1536,7 @@ Notice how we now instead output ``np.nan`` itself instead of a stringified form - Bug in :meth:`DataFrame.to_dict` when the resulting dict contains non-Python scalars in the case of numeric data (:issue:`23753`) - :func:`DataFrame.to_string()`, :func:`DataFrame.to_html()`, :func:`DataFrame.to_latex()` will correctly format output when a string is passed as the ``float_format`` argument (:issue:`21625`, :issue:`22270`) - Bug in :func:`read_csv` that caused it to raise ``OverflowError`` when trying to use 'inf' as ``na_value`` with integer index column (:issue:`17128`) +- Bug in :func:`read_fwf` in which the compression type of a file was not being properly inferred (:issue:`22199`) - Bug in :func:`pandas.io.json.json_normalize` that caused it to raise ``TypeError`` when two consecutive elements of ``record_path`` are dicts (:issue:`22706`) - Bug in :meth:`DataFrame.to_stata`, :class:`pandas.io.stata.StataWriter` and :class:`pandas.io.stata.StataWriter117` where a exception would leave a partially written and invalid dta file (:issue:`23573`) - Bug in :meth:`DataFrame.to_stata` and :class:`pandas.io.stata.StataWriter117` that produced invalid files when using strLs with non-ASCII characters (:issue:`23573`) diff --git a/pandas/io/parsers.py b/pandas/io/parsers.py index a85e5b3ea6539..de0ed9407e161 100755 --- a/pandas/io/parsers.py +++ b/pandas/io/parsers.py @@ -401,7 +401,7 @@ def _read(filepath_or_buffer, kwds): encoding = re.sub('_', '-', encoding).lower() kwds['encoding'] = encoding - compression = kwds.get('compression') + compression = kwds.get('compression', 'infer') compression = _infer_compression(filepath_or_buffer, compression) filepath_or_buffer, _, compression, should_close = get_filepath_or_buffer( filepath_or_buffer, encoding, compression) diff --git a/pandas/tests/io/parser/test_read_fwf.py b/pandas/tests/io/parser/test_read_fwf.py index e8c5b37579d71..172bbe0bad4c7 100644 --- a/pandas/tests/io/parser/test_read_fwf.py +++ b/pandas/tests/io/parser/test_read_fwf.py @@ -555,20 +555,26 @@ def test_default_delimiter(): tm.assert_frame_equal(result, expected) -@pytest.mark.parametrize("compression", ["gzip", "bz2"]) -def test_fwf_compression(compression): +@pytest.mark.parametrize("infer", [True, False, None]) +def test_fwf_compression(compression_only, infer): data = """1111111111 2222222222 3333333333""".strip() + compression = compression_only + extension = "gz" if compression == "gzip" else compression + kwargs = dict(widths=[5, 5], names=["one", "two"]) expected = read_fwf(StringIO(data), **kwargs) if compat.PY3: data = bytes(data, encoding="utf-8") - with tm.ensure_clean() as path: + with tm.ensure_clean(filename="tmp." + extension) as path: tm.write_to_compressed(compression, path, data) - result = read_fwf(path, compression=compression, **kwargs) + if infer is not None: + kwargs["compression"] = "infer" if infer else compression + + result = read_fwf(path, **kwargs) tm.assert_frame_equal(result, expected) From b66114d8cf9c5ab47fca0848807a4d78f322207c Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Thu, 27 Dec 2018 23:35:14 +0000 Subject: [PATCH 7/9] CI: Moving CircleCI build to Travis (#24449) --- .circleci/config.yml | 38 --------- .travis.yml | 7 ++ README.md | 8 -- ci/circle/install_circle.sh | 81 ------------------- ...e-36-locale.yaml => travis-36-locale.yaml} | 0 doc/source/contributing.rst | 13 ++- 6 files changed, 13 insertions(+), 134 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100755 ci/circle/install_circle.sh rename ci/deps/{circle-36-locale.yaml => travis-36-locale.yaml} (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 6b516b21722ac..0000000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: continuumio/miniconda:latest - # databases configuration - - image: circleci/postgres:9.6.5-alpine-ram - environment: - POSTGRES_USER: postgres - POSTGRES_DB: pandas_nosetest - - image: circleci/mysql:8-ram - environment: - MYSQL_USER: "root" - MYSQL_HOST: "localhost" - MYSQL_ALLOW_EMPTY_PASSWORD: "true" - MYSQL_DATABASE: "pandas_nosetest" - - environment: - JOB: "3.6_LOCALE" - ENV_FILE: "ci/deps/circle-36-locale.yaml" - LOCALE_OVERRIDE: "zh_CN.UTF-8" - MINICONDA_DIR: /home/ubuntu/miniconda3 - steps: - - checkout - - run: - name: build - command: | - ./ci/circle/install_circle.sh - export PATH="$MINICONDA_DIR/bin:$PATH" - source activate pandas-dev - python -c "import pandas; pandas.show_versions();" - - run: - name: test - command: | - export PATH="$MINICONDA_DIR/bin:$PATH" - source activate pandas-dev - echo "pytest -m "not slow and not network" --strict --durations=10 --color=no --junitxml=$CIRCLE_TEST_REPORTS/reports/junit.xml pandas" - pytest -m "not slow and not network" --strict --durations=10 --color=no --junitxml=$CIRCLE_TEST_REPORTS/reports/junit.xml pandas diff --git a/.travis.yml b/.travis.yml index c30a7f3f58f55..da17aaa1ad804 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ matrix: apt: packages: - language-pack-zh-hans + - dist: trusty env: - JOB="2.7" ENV_FILE="ci/deps/travis-27.yaml" PATTERN="not slow" @@ -50,9 +51,15 @@ matrix: apt: packages: - python-gtk2 + + - dist: trusty + env: + - JOB="3.6, locale" ENV_FILE="ci/deps/travis-36-locale.yaml" PATTERN="not slow and not network" LOCALE_OVERRIDE="zh_CN.UTF-8" + - dist: trusty env: - JOB="3.6, coverage" ENV_FILE="ci/deps/travis-36.yaml" PATTERN="not slow and not network" PANDAS_TESTING_MODE="deprecate" COVERAGE=true + - dist: trusty env: - JOB="3.7, NumPy dev" ENV_FILE="ci/deps/travis-37-numpydev.yaml" PATTERN="not slow and not network" TEST_ARGS="-W error" PANDAS_TESTING_MODE="deprecate" diff --git a/README.md b/README.md index be45faf06187e..ce22818705865 100644 --- a/README.md +++ b/README.md @@ -45,14 +45,6 @@ - - - - - circleci build status - - - diff --git a/ci/circle/install_circle.sh b/ci/circle/install_circle.sh deleted file mode 100755 index 0918e8790fca2..0000000000000 --- a/ci/circle/install_circle.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash - -home_dir=$(pwd) -echo "[home_dir: $home_dir]" - -echo "[ls -ltr]" -ls -ltr - -apt-get update -y && apt-get install -y build-essential postgresql-client-9.6 - -echo "[update conda]" -conda config --set ssl_verify false || exit 1 -conda config --set always_yes true --set changeps1 false || exit 1 -conda update -q conda - -# add the pandas channel to take priority -# to add extra packages -echo "[add channels]" -conda config --add channels pandas || exit 1 -conda config --remove channels defaults || exit 1 -conda config --add channels defaults || exit 1 - -# Useful for debugging any issues with conda -conda info -a || exit 1 - -# support env variables passed -export ENVS_FILE=".envs" - -# make sure that the .envs file exists. it is ok if it is empty -touch $ENVS_FILE - -# assume all command line arguments are environmental variables -for var in "$@" -do - echo "export $var" >> $ENVS_FILE -done - -echo "[environmental variable file]" -cat $ENVS_FILE -source $ENVS_FILE - -# edit the locale override if needed -if [ -n "$LOCALE_OVERRIDE" ]; then - - apt-get update && apt-get -y install locales locales-all - - export LANG=$LOCALE_OVERRIDE - export LC_ALL=$LOCALE_OVERRIDE - - python -c "import locale; locale.setlocale(locale.LC_ALL, \"$LOCALE_OVERRIDE\")" || exit 1; - - echo "[Adding locale to the first line of pandas/__init__.py]" - rm -f pandas/__init__.pyc - sedc="3iimport locale\nlocale.setlocale(locale.LC_ALL, \"$LOCALE_OVERRIDE\")\n" - sed -i "$sedc" pandas/__init__.py - echo "[head -4 pandas/__init__.py]" - head -4 pandas/__init__.py - echo -fi - -# create envbuild deps -echo "[create env]" -time conda env create -q --file="${ENV_FILE}" || exit 1 - -source activate pandas-dev - -# remove any installed pandas package -# w/o removing anything else -echo -echo "[removing installed pandas]" -conda remove pandas -y --force -pip uninstall -y pandas - -# build but don't install -echo "[build em]" -time python setup.py build_ext --inplace || exit 1 - -echo -echo "[show environment]" - -conda list diff --git a/ci/deps/circle-36-locale.yaml b/ci/deps/travis-36-locale.yaml similarity index 100% rename from ci/deps/circle-36-locale.yaml rename to ci/deps/travis-36-locale.yaml diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst index 281dbd72db161..a68e5c70087e9 100644 --- a/doc/source/contributing.rst +++ b/doc/source/contributing.rst @@ -686,13 +686,13 @@ See :ref:`contributing.warnings` for more. Testing With Continuous Integration ----------------------------------- -The *pandas* test suite will run automatically on `Travis-CI `__, -`Azure Pipelines `__, -and `Circle CI `__ continuous integration services, once your pull request is submitted. +The *pandas* test suite will run automatically on `Travis-CI `__ and +`Azure Pipelines `__ +continuous integration services, once your pull request is submitted. However, if you wish to run the test suite on a branch prior to submitting the pull request, then the continuous integration services need to be hooked to your GitHub repository. Instructions are here -for `Travis-CI `__, -`Azure Pipelines `__, and `CircleCI `__. +for `Travis-CI `__ and +`Azure Pipelines `__. A pull-request will be considered for merging when you have an all 'green' build. If any tests are failing, then you will get a red 'X', where you can click through to see the individual failed tests. @@ -704,8 +704,7 @@ This is an example of a green build. Each time you push to *your* fork, a *new* run of the tests will be triggered on the CI. You can enable the auto-cancel feature, which removes any non-currently-running tests for that same pull-request, for - `Travis-CI here `__ and - for `CircleCI here `__. + `Travis-CI here `__. .. _contributing.tdd: From 73801ab9cc0dee4637e52f16e571bba28e0f21c6 Mon Sep 17 00:00:00 2001 From: topper-123 Date: Thu, 27 Dec 2018 23:39:28 +0000 Subject: [PATCH 8/9] DOC: Correct location (#24456) --- doc/source/extending.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/extending.rst b/doc/source/extending.rst index 35d0dab7c3a77..3cb7e1ae019e1 100644 --- a/doc/source/extending.rst +++ b/doc/source/extending.rst @@ -162,7 +162,7 @@ your ``MyExtensionArray`` class, as follows: .. code-block:: python - from pandas.core.arrays import ExtensionArray, ExtensionScalarOpsMixin + from pandas.api.extensions import ExtensionArray, ExtensionScalarOpsMixin class MyExtensionArray(ExtensionArray, ExtensionScalarOpsMixin): pass From 24a50fc3028ff52ab37ea38911f34c05a746181c Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Thu, 27 Dec 2018 15:39:57 -0800 Subject: [PATCH 9/9] POC: _eadata (#24394) --- pandas/core/indexes/datetimelike.py | 64 ++++++++++++++++++---- pandas/core/indexes/datetimes.py | 14 ++--- pandas/core/indexes/period.py | 52 ++---------------- pandas/core/indexes/timedeltas.py | 39 ++++--------- pandas/tests/arithmetic/test_datetime64.py | 15 +++-- 5 files changed, 85 insertions(+), 99 deletions(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index e3d24bfbed7c3..685ad1101efb9 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -39,7 +39,6 @@ class DatetimeIndexOpsMixin(DatetimeLikeArrayMixin): # override DatetimeLikeArrayMixin method copy = Index.copy - unique = Index.unique # DatetimeLikeArrayMixin assumes subclasses are mutable, so these are # properties there. They can be made into cache_readonly for Index @@ -51,6 +50,30 @@ class DatetimeIndexOpsMixin(DatetimeLikeArrayMixin): _resolution = cache_readonly(DatetimeLikeArrayMixin._resolution.fget) resolution = cache_readonly(DatetimeLikeArrayMixin.resolution.fget) + def unique(self, level=None): + if level is not None: + self._validate_index_level(level) + + result = self._eadata.unique() + + # Note: if `self` is already unique, then self.unique() should share + # a `freq` with self. If not already unique, then self.freq must be + # None, so again sharing freq is correct. + return self._shallow_copy(result._data) + + @classmethod + def _create_comparison_method(cls, op): + """ + Create a comparison method that dispatches to ``cls.values``. + """ + def wrapper(self, other): + result = op(self._eadata, maybe_unwrap_index(other)) + return result + + wrapper.__doc__ = op.__doc__ + wrapper.__name__ = '__{}__'.format(op.__name__) + return wrapper + # A few methods that are shared _maybe_mask_results = DatetimeLikeArrayMixin._maybe_mask_results @@ -106,7 +129,7 @@ def wrapper(left, right): @Appender(DatetimeLikeArrayMixin._evaluate_compare.__doc__) def _evaluate_compare(self, other, op): - result = DatetimeLikeArrayMixin._evaluate_compare(self, other, op) + result = self._eadata._evaluate_compare(other, op) if is_bool_dtype(result): return result try: @@ -406,7 +429,7 @@ def _add_datetimelike_methods(cls): def __add__(self, other): # dispatch to ExtensionArray implementation - result = super(cls, self).__add__(other) + result = self._eadata.__add__(maybe_unwrap_index(other)) return wrap_arithmetic_op(self, other, result) cls.__add__ = __add__ @@ -418,13 +441,13 @@ def __radd__(self, other): def __sub__(self, other): # dispatch to ExtensionArray implementation - result = super(cls, self).__sub__(other) + result = self._eadata.__sub__(maybe_unwrap_index(other)) return wrap_arithmetic_op(self, other, result) cls.__sub__ = __sub__ def __rsub__(self, other): - result = super(cls, self).__rsub__(other) + result = self._eadata.__rsub__(maybe_unwrap_index(other)) return wrap_arithmetic_op(self, other, result) cls.__rsub__ = __rsub__ @@ -548,9 +571,8 @@ def astype(self, dtype, copy=True): @Appender(DatetimeLikeArrayMixin._time_shift.__doc__) def _time_shift(self, periods, freq=None): - result = DatetimeLikeArrayMixin._time_shift(self, periods, freq=freq) - result.name = self.name - return result + result = self._eadata._time_shift(periods, freq=freq) + return type(self)(result, name=self.name) def wrap_arithmetic_op(self, other, result): @@ -589,7 +611,7 @@ def wrap_array_method(method, pin_name=False): method """ def index_method(self, *args, **kwargs): - result = method(self, *args, **kwargs) + result = method(self._eadata, *args, **kwargs) # Index.__new__ will choose the appropriate subclass to return result = Index(result) @@ -618,7 +640,7 @@ def wrap_field_accessor(prop): fget = prop.fget def f(self): - result = fget(self) + result = fget(self._eadata) if is_bool_dtype(result): # return numpy array b/c there is no BoolIndex return result @@ -629,6 +651,28 @@ def f(self): return property(f) +def maybe_unwrap_index(obj): + """ + If operating against another Index object, we need to unwrap the underlying + data before deferring to the DatetimeArray/TimedeltaArray/PeriodArray + implementation, otherwise we will incorrectly return NotImplemented. + + Parameters + ---------- + obj : object + + Returns + ------- + unwrapped object + """ + if isinstance(obj, ABCIndexClass): + if isinstance(obj, DatetimeIndexOpsMixin): + # i.e. PeriodIndex/DatetimeIndex/TimedeltaIndex + return obj._eadata + return obj._data + return obj + + class DatetimelikeDelegateMixin(PandasDelegate): """ Delegation mechanism, specific for Datetime, Timedelta, and Period types. diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 09e741af363da..380341f05252c 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -713,15 +713,6 @@ def snap(self, freq='S'): return DatetimeIndex._simple_new(snapped, freq=freq) # TODO: what about self.name? tz? if so, use shallow_copy? - def unique(self, level=None): - if level is not None: - self._validate_index_level(level) - - # TODO(DatetimeArray): change dispatch once inheritance is removed - # call DatetimeArray method - result = DatetimeArray.unique(self) - return self._shallow_copy(result._data) - def join(self, other, how='left', level=None, return_indexers=False, sort=False): """ @@ -1089,6 +1080,11 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None): # -------------------------------------------------------------------- # Wrapping DatetimeArray + @property + def _eadata(self): + return DatetimeArray._simple_new(self._data, + tz=self.tz, freq=self.freq) + # Compat for frequency inference, see GH#23789 _is_monotonic_increasing = Index.is_monotonic_increasing _is_monotonic_decreasing = Index.is_monotonic_decreasing diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index b15604a57fb81..5f3102d15841f 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -26,7 +26,7 @@ import pandas.core.indexes.base as ibase from pandas.core.indexes.base import _index_shared_docs, ensure_index from pandas.core.indexes.datetimelike import ( - DatetimeIndexOpsMixin, DatetimelikeDelegateMixin, wrap_arithmetic_op) + DatetimeIndexOpsMixin, DatetimelikeDelegateMixin) from pandas.core.indexes.datetimes import DatetimeIndex, Index, Int64Index from pandas.core.missing import isna from pandas.core.ops import get_op_result_name @@ -247,6 +247,10 @@ def _simple_new(cls, values, name=None, freq=None, **kwargs): # ------------------------------------------------------------------------ # Data + @property + def _eadata(self): + return self._data + @property def _ndarray_values(self): return self._data._ndarray_values @@ -878,52 +882,6 @@ def __setstate__(self, state): _unpickle_compat = __setstate__ - @classmethod - def _add_datetimelike_methods(cls): - """ - add in the datetimelike methods (as we may have to override the - superclass) - """ - # TODO(DatetimeArray): move this up to DatetimeArrayMixin - - def __add__(self, other): - # dispatch to ExtensionArray implementation - result = self._data.__add__(other) - return wrap_arithmetic_op(self, other, result) - - cls.__add__ = __add__ - - def __radd__(self, other): - # alias for __add__ - return self.__add__(other) - cls.__radd__ = __radd__ - - def __sub__(self, other): - # dispatch to ExtensionArray implementation - result = self._data.__sub__(other) - return wrap_arithmetic_op(self, other, result) - - cls.__sub__ = __sub__ - - def __rsub__(self, other): - result = self._data.__rsub__(other) - return wrap_arithmetic_op(self, other, result) - - cls.__rsub__ = __rsub__ - - @classmethod - def _create_comparison_method(cls, op): - """ - Create a comparison method that dispatches to ``cls.values``. - """ - # TODO(DatetimeArray): move to base class. - def wrapper(self, other): - return op(self._data, other) - - wrapper.__doc__ = op.__doc__ - wrapper.__name__ = '__{}__'.format(op.__name__) - return wrapper - def view(self, dtype=None, type=None): # TODO(DatetimeArray): remove if dtype is None or dtype is __builtins__['type'](self): diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 47f7f7cf860fc..885902967d398 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -22,8 +22,8 @@ import pandas.core.common as com from pandas.core.indexes.base import Index, _index_shared_docs from pandas.core.indexes.datetimelike import ( - DatetimeIndexOpsMixin, wrap_arithmetic_op, wrap_array_method, - wrap_field_accessor) + DatetimeIndexOpsMixin, maybe_unwrap_index, wrap_arithmetic_op, + wrap_array_method, wrap_field_accessor) from pandas.core.indexes.numeric import Int64Index from pandas.core.ops import get_op_result_name from pandas.core.tools.timedeltas import _coerce_scalar_to_timedelta_type @@ -36,11 +36,7 @@ def _make_wrapped_arith_op(opname): meth = getattr(TimedeltaArray, opname) def method(self, other): - oth = other - if isinstance(other, Index): - oth = other._data - - result = meth(self, oth) + result = meth(self._eadata, maybe_unwrap_index(other)) return wrap_arithmetic_op(self, other, result) method.__name__ = opname @@ -237,6 +233,10 @@ def _format_native_types(self, na_rep=u'NaT', date_format=None, **kwargs): # ------------------------------------------------------------------- # Wrapping TimedeltaArray + @property + def _eadata(self): + return TimedeltaArray._simple_new(self._data, freq=self.freq) + __mul__ = _make_wrapped_arith_op("__mul__") __rmul__ = _make_wrapped_arith_op("__rmul__") __floordiv__ = _make_wrapped_arith_op("__floordiv__") @@ -245,6 +245,11 @@ def _format_native_types(self, na_rep=u'NaT', date_format=None, **kwargs): __rmod__ = _make_wrapped_arith_op("__rmod__") __divmod__ = _make_wrapped_arith_op("__divmod__") __rdivmod__ = _make_wrapped_arith_op("__rdivmod__") + __truediv__ = _make_wrapped_arith_op("__truediv__") + __rtruediv__ = _make_wrapped_arith_op("__rtruediv__") + if compat.PY2: + __div__ = __truediv__ + __rdiv__ = __rtruediv__ days = wrap_field_accessor(TimedeltaArray.days) seconds = wrap_field_accessor(TimedeltaArray.seconds) @@ -253,26 +258,6 @@ def _format_native_types(self, na_rep=u'NaT', date_format=None, **kwargs): total_seconds = wrap_array_method(TimedeltaArray.total_seconds, True) - def __truediv__(self, other): - oth = other - if isinstance(other, Index): - # TimedeltaArray defers, so we need to unwrap - oth = other._values - result = TimedeltaArray.__truediv__(self, oth) - return wrap_arithmetic_op(self, other, result) - - def __rtruediv__(self, other): - oth = other - if isinstance(other, Index): - # TimedeltaArray defers, so we need to unwrap - oth = other._values - result = TimedeltaArray.__rtruediv__(self, oth) - return wrap_arithmetic_op(self, other, result) - - if compat.PY2: - __div__ = __truediv__ - __rdiv__ = __rtruediv__ - # Compat for frequency inference, see GH#23789 _is_monotonic_increasing = Index.is_monotonic_increasing _is_monotonic_decreasing = Index.is_monotonic_decreasing diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index c7c487a04b2fd..3065785649359 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -1591,7 +1591,8 @@ def check(get_ser, test_ser): # with 'operate' (from core/ops.py) for the ops that are not # defined op = getattr(get_ser, op_str, None) - with pytest.raises(TypeError, match='operate|[cC]annot'): + with pytest.raises(TypeError, + match='operate|[cC]annot|unsupported operand'): op(test_ser) # ## timedelta64 ### @@ -1973,7 +1974,7 @@ def test_dti_sub_tdi(self, tz_naive_fixture): result = dti - tdi tm.assert_index_equal(result, expected) - msg = 'cannot subtract .*TimedeltaIndex' + msg = 'cannot subtract .*TimedeltaArrayMixin' with pytest.raises(TypeError, match=msg): tdi - dti @@ -1981,7 +1982,7 @@ def test_dti_sub_tdi(self, tz_naive_fixture): result = dti - tdi.values tm.assert_index_equal(result, expected) - msg = 'cannot subtract DatetimeIndex from' + msg = 'cannot subtract DatetimeArrayMixin from' with pytest.raises(TypeError, match=msg): tdi.values - dti @@ -1997,7 +1998,7 @@ def test_dti_isub_tdi(self, tz_naive_fixture): result -= tdi tm.assert_index_equal(result, expected) - msg = 'cannot subtract .*TimedeltaIndex' + msg = 'cannot subtract .*TimedeltaArrayMixin' with pytest.raises(TypeError, match=msg): tdi -= dti @@ -2008,7 +2009,7 @@ def test_dti_isub_tdi(self, tz_naive_fixture): msg = '|'.join(['cannot perform __neg__ with this index type:', 'ufunc subtract cannot use operands with types', - 'cannot subtract DatetimeIndex from']) + 'cannot subtract DatetimeArrayMixin from']) with pytest.raises(TypeError, match=msg): tdi.values -= dti @@ -2028,7 +2029,9 @@ def test_dti_isub_tdi(self, tz_naive_fixture): def test_add_datetimelike_and_dti(self, addend, tz): # GH#9631 dti = DatetimeIndex(['2011-01-01', '2011-01-02']).tz_localize(tz) - msg = 'cannot add DatetimeIndex and {0}'.format(type(addend).__name__) + msg = ('cannot add DatetimeArrayMixin and {0}' + .format(type(addend).__name__)).replace('DatetimeIndex', + 'DatetimeArrayMixin') with pytest.raises(TypeError, match=msg): dti + addend with pytest.raises(TypeError, match=msg):