Skip to content

Commit a586867

Browse files
committed
Merge pull request #8237 from jreback/pi
BUG: Bug in putting a PeriodIndex into a Series would convert to int64
2 parents 0d6264f + 1739fed commit a586867

File tree

8 files changed

+33
-15
lines changed

8 files changed

+33
-15
lines changed

doc/source/basics.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ This enables nice expressions like this:
11251125
.. ipython:: python
11261126
11271127
# period
1128-
s = Series(period_range('20130101',periods=4,freq='D').asobject)
1128+
s = Series(period_range('20130101',periods=4,freq='D'))
11291129
s
11301130
s.dt.year
11311131
s.dt.day

doc/source/v0.15.0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ This enables nice expressions like this:
369369
.. ipython:: python
370370

371371
# period
372-
s = Series(period_range('20130101',periods=4,freq='D').asobject)
372+
s = Series(period_range('20130101',periods=4,freq='D'))
373373
s
374374
s.dt.year
375375
s.dt.day
@@ -593,7 +593,7 @@ Bug Fixes
593593
- Bug in Panel when using ``major_xs`` and ``copy=False`` is passed (deprecation warning fails because of missing ``warnings``) (:issue:`8152`).
594594
- Bug in pickle deserialization that failed for pre-0.14.1 containers with dup items trying to avoid ambiguity
595595
when matching block and manager items, when there's only one block there's no ambiguity (:issue:`7794`)
596-
596+
- Bug in putting a ``PeriodIndex`` into a ``Series`` would convert to ``int64`` dtype, rather than ``object`` of ``Periods`` (:issue:`7932`)
597597
- Bug in HDFStore iteration when passing a where (:issue:`8014`)
598598
- Bug in DataFrameGroupby.transform when transforming with a passed non-sorted key (:issue:`8046`)
599599
- Bug in repeated timeseries line and area plot may result in ``ValueError`` or incorrect kind (:issue:`7733`)

pandas/core/algorithms.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,9 @@ def value_counts(values, sort=True, ascending=False, normalize=False,
196196
"""
197197
from pandas.core.series import Series
198198
from pandas.tools.tile import cut
199+
from pandas.tseries.period import PeriodIndex
199200

200-
is_period = getattr(values, 'inferred_type', None) == 'period'
201+
is_period = com.is_period_arraylike(values)
201202
values = Series(values).values
202203
is_category = com.is_categorical_dtype(values.dtype)
203204

@@ -215,6 +216,9 @@ def value_counts(values, sort=True, ascending=False, normalize=False,
215216
dtype = values.dtype
216217

217218
if issubclass(values.dtype.type, (np.datetime64, np.timedelta64)) or is_period:
219+
if is_period:
220+
values = PeriodIndex(values)
221+
218222
values = values.view(np.int64)
219223
keys, counts = htable.value_count_int64(values)
220224

pandas/core/common.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,13 @@ def is_iterator(obj):
23272327
def is_number(obj):
23282328
return isinstance(obj, (numbers.Number, np.number))
23292329

2330+
def is_period_arraylike(arr):
2331+
""" return if we are period arraylike / PeriodIndex """
2332+
if isinstance(arr, pd.PeriodIndex):
2333+
return True
2334+
elif isinstance(arr, (np.ndarray, ABCSeries)):
2335+
return arr.dtype == object and lib.infer_dtype(arr) == 'period'
2336+
return getattr(arr, 'inferred_type', None) == 'period'
23302337

23312338
def _coerce_to_dtype(dtype):
23322339
""" coerce a string / np.dtype to a dtype """
@@ -2382,7 +2389,6 @@ def is_datetime64_ns_dtype(arr_or_dtype):
23822389
tipo = _get_dtype(arr_or_dtype)
23832390
return tipo == _NS_DTYPE
23842391

2385-
23862392
def is_timedelta64_dtype(arr_or_dtype):
23872393
tipo = _get_dtype_type(arr_or_dtype)
23882394
return issubclass(tipo, np.timedelta64)

pandas/tests/test_series.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def get_expected(s, name):
110110
tm.assert_series_equal(s.dt.second,Series(np.array([0,1,2],dtype='int64'),index=index))
111111

112112
# periodindex
113-
for s in [Series(period_range('20130101',periods=5,freq='D').asobject)]:
113+
for s in [Series(period_range('20130101',periods=5,freq='D'))]:
114114

115115
for prop in ok_for_period:
116116
tm.assert_series_equal(getattr(s.dt,prop),get_expected(s,prop))
@@ -747,6 +747,15 @@ def test_constructor_dtype_datetime64(self):
747747
s = Series([pd.NaT, np.nan, '2013-08-05 15:30:00.000001'])
748748
self.assertEqual(s.dtype,'datetime64[ns]')
749749

750+
def test_constructor_periodindex(self):
751+
# GH7932
752+
# converting a PeriodIndex when put in a Series
753+
754+
pi = period_range('20130101',periods=5,freq='D')
755+
s = Series(pi)
756+
expected = Series(pi.asobject)
757+
assert_series_equal(s, expected)
758+
750759
def test_constructor_dict(self):
751760
d = {'a': 0., 'b': 1., 'c': 2.}
752761
result = Series(d, index=['b', 'c', 'd', 'a'])

pandas/tseries/common.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,9 @@ def maybe_to_datetimelike(data, copy=False):
3939
if issubclass(data.dtype.type, np.datetime64):
4040
return DatetimeProperties(DatetimeIndex(data, copy=copy), index)
4141
else:
42-
43-
if isinstance(data, PeriodIndex):
42+
if com.is_period_arraylike(data):
4443
return PeriodProperties(PeriodIndex(data, copy=copy), index)
4544

46-
data = com._values_from_object(data)
47-
inferred = lib.infer_dtype(data)
48-
if inferred == 'period':
49-
return PeriodProperties(PeriodIndex(data), index)
50-
5145
raise TypeError("cannot convert an object of type {0} to a datetimelike index".format(type(data)))
5246

5347
class Properties(PandasDelegate):

pandas/tseries/frequencies.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -664,9 +664,10 @@ def infer_freq(index, warn=True):
664664
if not (com.is_datetime64_dtype(index.values) or values.dtype == object):
665665
raise TypeError("cannot infer freq from a non-convertible dtype on a Series of {0}".format(index.dtype))
666666
index = values
667-
if isinstance(index, pd.PeriodIndex):
667+
668+
if com.is_period_arraylike(index):
668669
raise TypeError("PeriodIndex given. Check the `freq` attribute "
669-
"instead of using infer_freq.")
670+
"instead of using infer_freq.")
670671
if isinstance(index, pd.Index) and not isinstance(index, pd.DatetimeIndex):
671672
if isinstance(index, (pd.Int64Index, pd.Float64Index)):
672673
raise TypeError("cannot infer freq from a non-convertible index type {0}".format(type(index)))

pandas/tseries/period.py

+4
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,10 @@ def __contains__(self, key):
746746
def _box_func(self):
747747
return lambda x: Period._from_ordinal(ordinal=x, freq=self.freq)
748748

749+
def _to_embed(self, keep_tz=False):
750+
""" return an array repr of this object, potentially casting to object """
751+
return self.asobject.values
752+
749753
def asof_locs(self, where, mask):
750754
"""
751755
where : array of timestamps

0 commit comments

Comments
 (0)