Skip to content

Commit 52064fc

Browse files
committed
Merge branch 'master' of https://github.com/pandas-dev/pandas into ref-liboffsets-cdefit
2 parents 5c7c89b + 0cb7a1f commit 52064fc

File tree

5 files changed

+36
-49
lines changed

5 files changed

+36
-49
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ matrix:
7575

7676
before_install:
7777
- echo "before_install"
78-
# set non-blocking IO on travis
79-
# https://github.com/travis-ci/travis-ci/issues/8920#issuecomment-352661024
78+
# Use blocking IO on travis. Ref: https://github.com/travis-ci/travis-ci/issues/8920#issuecomment-352661024
8079
- python -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK);'
8180
- source ci/travis_process_gbq_encryption.sh
8281
- export PATH="$HOME/miniconda3/bin:$PATH"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
[![Downloads](https://anaconda.org/conda-forge/pandas/badges/downloads.svg)](https://pandas.pydata.org)
1717
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pydata/pandas)
1818
[![Powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A)](https://numfocus.org)
19+
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
1920

2021
## What is it?
2122

doc/source/ecosystem.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ substantial projects that you feel should be on this list, please let us know.
3030
Data cleaning and validation
3131
----------------------------
3232

33-
`pyjanitor <https://github.com/ericmjl/pyjanitor/>`__
33+
`Pyjanitor <https://github.com/ericmjl/pyjanitor/>`__
3434
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3535

3636
Pyjanitor provides a clean API for cleaning data, using method chaining.
@@ -115,7 +115,7 @@ It is very similar to the matplotlib plotting backend, but provides interactive
115115
web-based charts and maps.
116116

117117

118-
`seaborn <https://seaborn.pydata.org>`__
118+
`Seaborn <https://seaborn.pydata.org>`__
119119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120120

121121
Seaborn is a Python visualization library based on
@@ -136,7 +136,7 @@ provides a powerful, declarative and extremely general way to generate bespoke p
136136
Various implementations to other languages are available.
137137
A good implementation for Python users is `has2k1/plotnine <https://github.com/has2k1/plotnine/>`__.
138138

139-
`IPython Vega <https://github.com/vega/ipyvega>`__
139+
`IPython vega <https://github.com/vega/ipyvega>`__
140140
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141141

142142
`IPython Vega <https://github.com/vega/ipyvega>`__ leverages `Vega
@@ -147,7 +147,7 @@ A good implementation for Python users is `has2k1/plotnine <https://github.com/h
147147

148148
`Plotly’s <https://plot.ly/>`__ `Python API <https://plot.ly/python/>`__ enables interactive figures and web shareability. Maps, 2D, 3D, and live-streaming graphs are rendered with WebGL and `D3.js <https://d3js.org/>`__. The library supports plotting directly from a pandas DataFrame and cloud-based collaboration. Users of `matplotlib, ggplot for Python, and Seaborn <https://plot.ly/python/matplotlib-to-plotly-tutorial/>`__ can convert figures into interactive web-based plots. Plots can be drawn in `IPython Notebooks <https://plot.ly/ipython-notebooks/>`__ , edited with R or MATLAB, modified in a GUI, or embedded in apps and dashboards. Plotly is free for unlimited sharing, and has `cloud <https://plot.ly/product/plans/>`__, `offline <https://plot.ly/python/offline/>`__, or `on-premise <https://plot.ly/product/enterprise/>`__ accounts for private use.
149149

150-
`QtPandas <https://github.com/draperjames/qtpandas>`__
150+
`Qtpandas <https://github.com/draperjames/qtpandas>`__
151151
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152152

153153
Spun off from the main pandas library, the `qtpandas <https://github.com/draperjames/qtpandas>`__
@@ -187,7 +187,7 @@ See :ref:`Options and Settings <options>` and
187187
:ref:`Available Options <options.available>`
188188
for pandas ``display.`` settings.
189189

190-
`quantopian/qgrid <https://github.com/quantopian/qgrid>`__
190+
`Quantopian/qgrid <https://github.com/quantopian/qgrid>`__
191191
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
192192

193193
qgrid is "an interactive grid for sorting and filtering
@@ -249,12 +249,12 @@ The following data feeds are available:
249249
* Stooq Index Data
250250
* MOEX Data
251251

252-
`quandl/Python <https://github.com/quandl/Python>`__
252+
`Quandl/Python <https://github.com/quandl/Python>`__
253253
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
254254
Quandl API for Python wraps the Quandl REST API to return
255255
Pandas DataFrames with timeseries indexes.
256256

257-
`pydatastream <https://github.com/vfilimonov/pydatastream>`__
257+
`Pydatastream <https://github.com/vfilimonov/pydatastream>`__
258258
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259259
PyDatastream is a Python interface to the
260260
`Refinitiv Datastream (DWS) <https://www.refinitiv.com/en/products/datastream-macroeconomic-analysis>`__
@@ -384,7 +384,7 @@ Pandas provides an interface for defining
384384
system. The following libraries implement that interface to provide types not
385385
found in NumPy or pandas, which work well with pandas' data containers.
386386

387-
`cyberpandas`_
387+
`Cyberpandas`_
388388
~~~~~~~~~~~~~~
389389

390390
Cyberpandas provides an extension type for storing arrays of IP Addresses. These
@@ -411,4 +411,4 @@ Library Accessor Classes Description
411411
.. _pdvega: https://altair-viz.github.io/pdvega/
412412
.. _Altair: https://altair-viz.github.io/
413413
.. _pandas_path: https://github.com/drivendataorg/pandas-path/
414-
.. _pathlib.Path: https://docs.python.org/3/library/pathlib.html
414+
.. _pathlib.Path: https://docs.python.org/3/library/pathlib.html

pandas/_libs/tslibs/offsets.pyx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -859,10 +859,13 @@ cdef class _Tick(_BaseOffset):
859859
self.normalize = False
860860

861861

862-
class BusinessMixin:
862+
class BusinessMixin(BaseOffset):
863863
"""
864864
Mixin to business types to provide related functions.
865865
"""
866+
def __init__(self, n=1, normalize=False, offset=timedelta(0)):
867+
BaseOffset.__init__(self, n, normalize)
868+
object.__setattr__(self, "_offset", offset)
866869

867870
@property
868871
def offset(self):
@@ -886,7 +889,11 @@ class BusinessMixin:
886889
class BusinessHourMixin(BusinessMixin):
887890
_adjust_dst = False
888891

889-
def __init__(self, start="09:00", end="17:00", offset=timedelta(0)):
892+
def __init__(
893+
self, n=1, normalize=False, start="09:00", end="17:00", offset=timedelta(0)
894+
):
895+
BusinessMixin.__init__(self, n, normalize, offset)
896+
890897
# must be validated here to equality check
891898
if np.ndim(start) == 0:
892899
# i.e. not is_list_like
@@ -930,7 +937,6 @@ class BusinessHourMixin(BusinessMixin):
930937

931938
object.__setattr__(self, "start", start)
932939
object.__setattr__(self, "end", end)
933-
object.__setattr__(self, "_offset", offset)
934940

935941
def _repr_attrs(self) -> str:
936942
out = super()._repr_attrs()

pandas/tseries/offsets.py

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,6 @@ def __reduce__(self):
339339
tup = (self.n, self.normalize, self.offset)
340340
return type(self), tup
341341

342-
def __init__(self, n=1, normalize=False, offset=timedelta(0)):
343-
BaseOffset.__init__(self, n, normalize)
344-
object.__setattr__(self, "_offset", offset)
345-
346342
def _offset_str(self) -> str:
347343
def get_str(td):
348344
off_str = ""
@@ -442,7 +438,15 @@ def is_on_offset(self, dt: datetime) -> bool:
442438
return dt.weekday() < 5
443439

444440

445-
class BusinessHourMixin(liboffsets.BusinessHourMixin):
441+
class BusinessHour(SingleConstructorMixin, liboffsets.BusinessHourMixin):
442+
"""
443+
DateOffset subclass representing possibly n business hours.
444+
"""
445+
446+
_prefix = "BH"
447+
_anchor = 0
448+
_attributes = frozenset(["n", "normalize", "start", "end", "offset"])
449+
446450
@cache_readonly
447451
def next_bday(self):
448452
"""
@@ -702,22 +706,6 @@ def _is_on_offset(self, dt):
702706
return False
703707

704708

705-
class BusinessHour(BusinessHourMixin, SingleConstructorOffset):
706-
"""
707-
DateOffset subclass representing possibly n business hours.
708-
"""
709-
710-
_prefix = "BH"
711-
_anchor = 0
712-
_attributes = frozenset(["n", "normalize", "start", "end", "offset"])
713-
714-
def __init__(
715-
self, n=1, normalize=False, start="09:00", end="17:00", offset=timedelta(0)
716-
):
717-
BaseOffset.__init__(self, n, normalize)
718-
super().__init__(start=start, end=end, offset=offset)
719-
720-
721709
class CustomBusinessDay(CustomMixin, BusinessDay):
722710
"""
723711
DateOffset subclass representing custom business days excluding holidays.
@@ -756,9 +744,7 @@ def __init__(
756744
calendar=None,
757745
offset=timedelta(0),
758746
):
759-
BaseOffset.__init__(self, n, normalize)
760-
object.__setattr__(self, "_offset", offset)
761-
747+
BusinessDay.__init__(self, n, normalize, offset)
762748
CustomMixin.__init__(self, weekmask, holidays, calendar)
763749

764750
@apply_wraps
@@ -801,7 +787,7 @@ def is_on_offset(self, dt: datetime) -> bool:
801787
return np.is_busday(day64, busdaycal=self.calendar)
802788

803789

804-
class CustomBusinessHour(CustomMixin, BusinessHourMixin, SingleConstructorOffset):
790+
class CustomBusinessHour(CustomMixin, BusinessHour):
805791
"""
806792
DateOffset subclass representing possibly n custom business days.
807793
"""
@@ -823,11 +809,8 @@ def __init__(
823809
end="17:00",
824810
offset=timedelta(0),
825811
):
826-
BaseOffset.__init__(self, n, normalize)
827-
object.__setattr__(self, "_offset", offset)
828-
812+
BusinessHour.__init__(self, n, normalize, start=start, end=end, offset=offset)
829813
CustomMixin.__init__(self, weekmask, holidays, calendar)
830-
BusinessHourMixin.__init__(self, start=start, end=end, offset=offset)
831814

832815

833816
# ---------------------------------------------------------------------
@@ -927,9 +910,7 @@ def __init__(
927910
calendar=None,
928911
offset=timedelta(0),
929912
):
930-
BaseOffset.__init__(self, n, normalize)
931-
object.__setattr__(self, "_offset", offset)
932-
913+
BusinessMixin.__init__(self, n, normalize, offset)
933914
CustomMixin.__init__(self, weekmask, holidays, calendar)
934915

935916
@cache_readonly
@@ -1009,9 +990,9 @@ def __init__(self, n=1, normalize=False, day_of_month=None):
1009990
BaseOffset.__init__(self, n, normalize)
1010991

1011992
if day_of_month is None:
1012-
object.__setattr__(self, "day_of_month", self._default_day_of_month)
1013-
else:
1014-
object.__setattr__(self, "day_of_month", int(day_of_month))
993+
day_of_month = self._default_day_of_month
994+
995+
object.__setattr__(self, "day_of_month", int(day_of_month))
1015996
if not self._min_day_of_month <= self.day_of_month <= 27:
1016997
raise ValueError(
1017998
"day_of_month must be "

0 commit comments

Comments
 (0)