Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c46fbe0

Browse files
authoredMay 25, 2018
Merge branch 'master' into bugfix/zip
2 parents 74b8c34 + f6abb61 commit c46fbe0

34 files changed

+472
-160
lines changed
 

‎ci/travis-36.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ dependencies:
1818
- numexpr
1919
- numpy
2020
- openpyxl
21-
- pandas-datareader
2221
- psycopg2
2322
- pyarrow
2423
- pymysql
2524
- pytables
26-
- python-dateutil
2725
- python-snappy
2826
- python=3.6*
2927
- pytz
@@ -45,3 +43,5 @@ dependencies:
4543
- pip:
4644
- brotlipy
4745
- coverage
46+
- pandas-datareader
47+
- python-dateutil

‎doc/source/advanced.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,55 @@ bins, with ``NaN`` representing a missing value similar to other dtypes.
924924
925925
pd.cut([0, 3, 5, 1], bins=c.categories)
926926
927+
928+
Generating Ranges of Intervals
929+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
930+
931+
If we need intervals on a regular frequency, we can use the :func:`interval_range` function
932+
to create an ``IntervalIndex`` using various combinations of ``start``, ``end``, and ``periods``.
933+
The default frequency for ``interval_range`` is a 1 for numeric intervals, and calendar day for
934+
datetime-like intervals:
935+
936+
.. ipython:: python
937+
938+
pd.interval_range(start=0, end=5)
939+
940+
pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=4)
941+
942+
pd.interval_range(end=pd.Timedelta('3 days'), periods=3)
943+
944+
The ``freq`` parameter can used to specify non-default frequencies, and can utilize a variety
945+
of :ref:`frequency aliases <timeseries.offset_aliases>` with datetime-like intervals:
946+
947+
.. ipython:: python
948+
949+
pd.interval_range(start=0, periods=5, freq=1.5)
950+
951+
pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=4, freq='W')
952+
953+
pd.interval_range(start=pd.Timedelta('0 days'), periods=3, freq='9H')
954+
955+
Additionally, the ``closed`` parameter can be used to specify which side(s) the intervals
956+
are closed on. Intervals are closed on the right side by default.
957+
958+
.. ipython:: python
959+
960+
pd.interval_range(start=0, end=4, closed='both')
961+
962+
pd.interval_range(start=0, end=4, closed='neither')
963+
964+
.. versionadded:: 0.23.0
965+
966+
Specifying ``start``, ``end``, and ``periods`` will generate a range of evenly spaced
967+
intervals from ``start`` to ``end`` inclusively, with ``periods`` number of elements
968+
in the resulting ``IntervalIndex``:
969+
970+
.. ipython:: python
971+
972+
pd.interval_range(start=0, end=6, periods=4)
973+
974+
pd.interval_range(pd.Timestamp('2018-01-01'), pd.Timestamp('2018-02-28'), periods=3)
975+
927976
Miscellaneous indexing FAQ
928977
--------------------------
929978

‎doc/source/api.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,6 @@ Modifying and Computations
14591459
Index.is_floating
14601460
Index.is_integer
14611461
Index.is_interval
1462-
Index.is_lexsorted_for_tuple
14631462
Index.is_mixed
14641463
Index.is_numeric
14651464
Index.is_object
@@ -1471,11 +1470,19 @@ Modifying and Computations
14711470
Index.where
14721471
Index.take
14731472
Index.putmask
1474-
Index.set_names
14751473
Index.unique
14761474
Index.nunique
14771475
Index.value_counts
14781476

1477+
Compatibility with MultiIndex
1478+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1479+
.. autosummary::
1480+
:toctree: generated/
1481+
1482+
Index.set_names
1483+
Index.is_lexsorted_for_tuple
1484+
Index.droplevel
1485+
14791486
Missing Values
14801487
~~~~~~~~~~~~~~
14811488
.. autosummary::

‎doc/source/timedeltas.rst

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ You can convert a ``Timedelta`` to an `ISO 8601 Duration`_ string with the
352352
TimedeltaIndex
353353
--------------
354354

355-
To generate an index with time delta, you can use either the ``TimedeltaIndex`` or
356-
the ``timedelta_range`` constructor.
355+
To generate an index with time delta, you can use either the :class:`TimedeltaIndex` or
356+
the :func:`timedelta_range` constructor.
357357

358358
Using ``TimedeltaIndex`` you can pass string-like, ``Timedelta``, ``timedelta``,
359359
or ``np.timedelta64`` objects. Passing ``np.nan/pd.NaT/nat`` will represent missing values.
@@ -363,13 +363,47 @@ or ``np.timedelta64`` objects. Passing ``np.nan/pd.NaT/nat`` will represent miss
363363
pd.TimedeltaIndex(['1 days', '1 days, 00:00:05',
364364
np.timedelta64(2,'D'), datetime.timedelta(days=2,seconds=2)])
365365
366-
Similarly to ``date_range``, you can construct regular ranges of a ``TimedeltaIndex``:
366+
Generating Ranges of Time Deltas
367+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
368+
369+
Similar to :func:`date_range`, you can construct regular ranges of a ``TimedeltaIndex``
370+
using :func:`timedelta_range`. The default frequency for ``timedelta_range`` is
371+
calendar day:
372+
373+
.. ipython:: python
374+
375+
pd.timedelta_range(start='1 days', periods=5)
376+
377+
Various combinations of ``start``, ``end``, and ``periods`` can be used with
378+
``timedelta_range``:
379+
380+
.. ipython:: python
381+
382+
pd.timedelta_range(start='1 days', end='5 days')
383+
384+
pd.timedelta_range(end='10 days', periods=4)
385+
386+
The ``freq`` parameter can passed a variety of :ref:`frequency aliases <timeseries.offset_aliases>`:
367387

368388
.. ipython:: python
369389
370-
pd.timedelta_range(start='1 days', periods=5, freq='D')
371390
pd.timedelta_range(start='1 days', end='2 days', freq='30T')
372391
392+
pd.timedelta_range(start='1 days', periods=5, freq='2D5H')
393+
394+
395+
.. versionadded:: 0.23.0
396+
397+
Specifying ``start``, ``end``, and ``periods`` will generate a range of evenly spaced
398+
timedeltas from ``start`` to ``end`` inclusively, with ``periods`` number of elements
399+
in the resulting ``TimedeltaIndex``:
400+
401+
.. ipython:: python
402+
403+
pd.timedelta_range('0 days', '4 days', periods=5)
404+
405+
pd.timedelta_range('0 days', '4 days', periods=10)
406+
373407
Using the TimedeltaIndex
374408
~~~~~~~~~~~~~~~~~~~~~~~~
375409

‎doc/source/timeseries.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,18 @@ of those specified will not be generated:
393393
394394
pd.bdate_range(start=start, periods=20)
395395
396+
.. versionadded:: 0.23.0
397+
398+
Specifying ``start``, ``end``, and ``periods`` will generate a range of evenly spaced
399+
dates from ``start`` to ``end`` inclusively, with ``periods`` number of elements in the
400+
resulting ``DatetimeIndex``:
401+
402+
.. ipython:: python
403+
404+
pd.date_range('2018-01-01', '2018-01-05', periods=5)
405+
406+
pd.date_range('2018-01-01', '2018-01-05', periods=10)
407+
396408
.. _timeseries.custom-freq-ranges:
397409

398410
Custom Frequency Ranges

‎doc/source/whatsnew/v0.23.1.txt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and bug fixes. We recommend that all users upgrade to this version.
1515
New features
1616
~~~~~~~~~~~~
1717

18+
- :meth:`Index.droplevel` is now implemented also for flat indexes, for compatibility with MultiIndex (:issue:`21115`)
19+
1820

1921
.. _whatsnew_0231.deprecations:
2022

@@ -44,6 +46,8 @@ Documentation Changes
4446
Bug Fixes
4547
~~~~~~~~~
4648

49+
- tab completion on :class:`Index` in IPython no longer outputs deprecation warnings (:issue:`21125`)
50+
4751
Groupby/Resample/Rolling
4852
^^^^^^^^^^^^^^^^^^^^^^^^
4953

@@ -53,7 +57,10 @@ Strings
5357
^^^^^^^
5458

5559
- Bug in :meth:`Series.str.replace()` where the method throws `TypeError` on Python 3.5.2 (:issue: `21078`)
56-
-
60+
61+
Timedelta
62+
^^^^^^^^^
63+
- Bug in :class:`Timedelta`: where passing a float with a unit would prematurely round the float precision (:issue: `14156`)
5764

5865
Categorical
5966
^^^^^^^^^^^
@@ -70,12 +77,14 @@ Indexing
7077
^^^^^^^^
7178

7279
- Bug in :meth:`Series.reset_index` where appropriate error was not raised with an invalid level name (:issue:`20925`)
80+
- Bug in :func:`interval_range` when ``start``/``periods`` or ``end``/``periods`` are specified with float ``start`` or ``end`` (:issue:`21161`)
7381
-
7482

7583
I/O
7684
^^^
7785

7886
- Bug in :class:`pandas.io.common.BytesZipFile` where zip compression produces uncompressed zip archive (:issue:`17778`)
87+
- Bug in :meth:`DataFrame.to_stata` which prevented exporting DataFrames to buffers and most file-like objects (:issue:`21041`)
7988
-
8089

8190
Plotting
@@ -87,10 +96,5 @@ Plotting
8796
Reshaping
8897
^^^^^^^^^
8998

90-
-
91-
-
92-
93-
Categorical
94-
^^^^^^^^^^^
95-
99+
- Bug in :func:`concat` where error was raised in concatenating :class:`Series` with numpy scalar and tuple names (:issue:`21015`)
96100
-

‎pandas/_libs/tslibs/timedeltas.pyx

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,22 @@ cpdef inline int64_t cast_from_unit(object ts, object unit) except? -1:
202202

203203
if unit == 'D' or unit == 'd':
204204
m = 1000000000L * 86400
205-
p = 6
205+
p = 9
206206
elif unit == 'h':
207207
m = 1000000000L * 3600
208-
p = 6
208+
p = 9
209209
elif unit == 'm':
210210
m = 1000000000L * 60
211-
p = 6
211+
p = 9
212212
elif unit == 's':
213213
m = 1000000000L
214-
p = 6
214+
p = 9
215215
elif unit == 'ms':
216216
m = 1000000L
217-
p = 3
217+
p = 6
218218
elif unit == 'us':
219219
m = 1000L
220-
p = 0
220+
p = 3
221221
elif unit == 'ns' or unit is None:
222222
m = 1L
223223
p = 0
@@ -231,10 +231,10 @@ cpdef inline int64_t cast_from_unit(object ts, object unit) except? -1:
231231
# cast the unit, multiply base/frace separately
232232
# to avoid precision issues from float -> int
233233
base = <int64_t> ts
234-
frac = ts -base
234+
frac = ts - base
235235
if p:
236236
frac = round(frac, p)
237-
return <int64_t> (base *m) + <int64_t> (frac *m)
237+
return <int64_t> (base * m) + <int64_t> (frac * m)
238238

239239

240240
cdef inline _decode_if_necessary(object ts):
@@ -760,7 +760,32 @@ cdef class _Timedelta(timedelta):
760760

761761
@property
762762
def delta(self):
763-
""" return out delta in ns (for internal compat) """
763+
"""
764+
Return the timedelta in nanoseconds (ns), for internal compatibility.
765+
766+
Returns
767+
-------
768+
int
769+
Timedelta in nanoseconds.
770+
771+
Examples
772+
--------
773+
>>> td = pd.Timedelta('1 days 42 ns')
774+
>>> td.delta
775+
86400000000042
776+
777+
>>> td = pd.Timedelta('3 s')
778+
>>> td.delta
779+
3000000000
780+
781+
>>> td = pd.Timedelta('3 ms 5 us')
782+
>>> td.delta
783+
3005000
784+
785+
>>> td = pd.Timedelta(42, unit='ns')
786+
>>> td.delta
787+
42
788+
"""
764789
return self.value
765790

766791
@property
@@ -1221,7 +1246,7 @@ class Timedelta(_Timedelta):
12211246
deprecated. Use 'array // timedelta.value' instead.
12221247
If you want to obtain epochs from an array of timestamps,
12231248
you can rather use
1224-
'array - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")'.
1249+
'(array - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")'.
12251250
""")
12261251
warnings.warn(msg, FutureWarning)
12271252
return other // self.value

‎pandas/core/accessor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
class DirNamesMixin(object):
1414
_accessors = frozenset([])
15-
_deprecations = frozenset(['asobject'])
15+
_deprecations = frozenset(
16+
['asobject', 'base', 'data', 'flags', 'itemsize', 'strides'])
1617

1718
def _dir_deletions(self):
1819
""" delete unwanted __dir__ for this object """

‎pandas/core/common.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ def flatten(l):
5555
def _consensus_name_attr(objs):
5656
name = objs[0].name
5757
for obj in objs[1:]:
58-
if obj.name != name:
59-
return None
58+
try:
59+
if obj.name != name:
60+
name = None
61+
except ValueError:
62+
name = None
6063
return name
6164

6265

‎pandas/core/frame.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,8 +1774,11 @@ def to_stata(self, fname, convert_dates=None, write_index=True,
17741774
17751775
Parameters
17761776
----------
1777-
fname : str or buffer
1778-
String path of file-like object.
1777+
fname : path (string), buffer or path object
1778+
string, path object (pathlib.Path or py._path.local.LocalPath) or
1779+
object implementing a binary write() functions. If using a buffer
1780+
then the buffer will not be automatically closed after the file
1781+
data has been written.
17791782
convert_dates : dict
17801783
Dictionary mapping columns containing datetime types to stata
17811784
internal format to use when writing the dates. Options are 'tc',
@@ -4096,9 +4099,8 @@ def _maybe_casted_values(index, labels=None):
40964099
if not isinstance(level, (tuple, list)):
40974100
level = [level]
40984101
level = [self.index._get_level_number(lev) for lev in level]
4099-
if isinstance(self.index, MultiIndex):
4100-
if len(level) < self.index.nlevels:
4101-
new_index = self.index.droplevel(level)
4102+
if len(level) < self.index.nlevels:
4103+
new_index = self.index.droplevel(level)
41024104

41034105
if not drop:
41044106
if isinstance(self.index, MultiIndex):
@@ -4175,8 +4177,9 @@ def dropna(self, axis=0, how='any', thresh=None, subset=None,
41754177
* 0, or 'index' : Drop rows which contain missing values.
41764178
* 1, or 'columns' : Drop columns which contain missing value.
41774179
4178-
.. deprecated:: 0.23.0: Pass tuple or list to drop on multiple
4179-
axes.
4180+
.. deprecated:: 0.23.0
4181+
Pass tuple or list to drop on multiple axes.
4182+
41804183
how : {'any', 'all'}, default 'any'
41814184
Determine if row or column is removed from DataFrame, when we have
41824185
at least one NA or all NA.

0 commit comments

Comments
 (0)
Please sign in to comment.