Skip to content

BUG: Bug in putting a PeriodIndex into a Series would convert to int64 #8237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ This enables nice expressions like this:
.. ipython:: python

# period
s = Series(period_range('20130101',periods=4,freq='D').asobject)
s = Series(period_range('20130101',periods=4,freq='D'))
s
s.dt.year
s.dt.day
Expand Down
8 changes: 4 additions & 4 deletions doc/source/v0.15.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ API changes
2 6
3 NaN
dtype: float64

New behavior (note final value is ``5 = sum([2, 3, NaN])``):

.. ipython:: python
Expand Down Expand Up @@ -139,7 +139,7 @@ API changes
4 1.571429
5 2.189189
dtype: float64

New behavior (note values start at index ``4``, the location of the 2nd (since ``min_periods=2``) non-empty value):

.. ipython:: python
Expand Down Expand Up @@ -369,7 +369,7 @@ This enables nice expressions like this:
.. ipython:: python

# period
s = Series(period_range('20130101',periods=4,freq='D').asobject)
s = Series(period_range('20130101',periods=4,freq='D'))
s
s.dt.year
s.dt.day
Expand Down Expand Up @@ -593,7 +593,7 @@ Bug Fixes
- Bug in Panel when using ``major_xs`` and ``copy=False`` is passed (deprecation warning fails because of missing ``warnings``) (:issue:`8152`).
- Bug in pickle deserialization that failed for pre-0.14.1 containers with dup items trying to avoid ambiguity
when matching block and manager items, when there's only one block there's no ambiguity (:issue:`7794`)

- Bug in putting a ``PeriodIndex`` into a ``Series`` would convert to ``int64`` dtype, rather than ``object`` of ``Periods`` (:issue:`7932`)
- Bug in HDFStore iteration when passing a where (:issue:`8014`)
- Bug in DataFrameGroupby.transform when transforming with a passed non-sorted key (:issue:`8046`)
- Bug in repeated timeseries line and area plot may result in ``ValueError`` or incorrect kind (:issue:`7733`)
Expand Down
6 changes: 5 additions & 1 deletion pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ def value_counts(values, sort=True, ascending=False, normalize=False,
"""
from pandas.core.series import Series
from pandas.tools.tile import cut
from pandas.tseries.period import PeriodIndex

is_period = getattr(values, 'inferred_type', None) == 'period'
is_period = com.is_period_arraylike(values)
values = Series(values).values
is_category = com.is_categorical_dtype(values.dtype)

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

if issubclass(values.dtype.type, (np.datetime64, np.timedelta64)) or is_period:
if is_period:
values = PeriodIndex(values)

values = values.view(np.int64)
keys, counts = htable.value_count_int64(values)

Expand Down
8 changes: 7 additions & 1 deletion pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,13 @@ def is_iterator(obj):
def is_number(obj):
return isinstance(obj, (numbers.Number, np.number))

def is_period_arraylike(arr):
""" return if we are period arraylike / PeriodIndex """
if isinstance(arr, pd.PeriodIndex):
return True
elif isinstance(arr, (np.ndarray, ABCSeries)):
return arr.dtype == object and lib.infer_dtype(arr) == 'period'
return getattr(arr, 'inferred_type', None) == 'period'

def _coerce_to_dtype(dtype):
""" coerce a string / np.dtype to a dtype """
Expand Down Expand Up @@ -2380,7 +2387,6 @@ def is_datetime64_ns_dtype(arr_or_dtype):
tipo = _get_dtype(arr_or_dtype)
return tipo == _NS_DTYPE


def is_timedelta64_dtype(arr_or_dtype):
tipo = _get_dtype_type(arr_or_dtype)
return issubclass(tipo, np.timedelta64)
Expand Down
11 changes: 10 additions & 1 deletion pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def get_expected(s, name):
tm.assert_series_equal(s.dt.second,Series(np.array([0,1,2],dtype='int64'),index=index))

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

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

def test_constructor_periodindex(self):
# GH7932
# converting a PeriodIndex when put in a Series

pi = period_range('20130101',periods=5,freq='D')
s = Series(pi)
expected = Series(pi.asobject)
assert_series_equal(s, expected)

def test_constructor_dict(self):
d = {'a': 0., 'b': 1., 'c': 2.}
result = Series(d, index=['b', 'c', 'd', 'a'])
Expand Down
8 changes: 1 addition & 7 deletions pandas/tseries/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,9 @@ def maybe_to_datetimelike(data, copy=False):
if issubclass(data.dtype.type, np.datetime64):
return DatetimeProperties(DatetimeIndex(data, copy=copy), index)
else:

if isinstance(data, PeriodIndex):
if com.is_period_arraylike(data):
return PeriodProperties(PeriodIndex(data, copy=copy), index)

data = com._values_from_object(data)
inferred = lib.infer_dtype(data)
if inferred == 'period':
return PeriodProperties(PeriodIndex(data), index)

raise TypeError("cannot convert an object of type {0} to a datetimelike index".format(type(data)))

class Properties(PandasDelegate):
Expand Down
5 changes: 3 additions & 2 deletions pandas/tseries/frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,10 @@ def infer_freq(index, warn=True):
if not (com.is_datetime64_dtype(index.values) or values.dtype == object):
raise TypeError("cannot infer freq from a non-convertible dtype on a Series of {0}".format(index.dtype))
index = values
if isinstance(index, pd.PeriodIndex):

if com.is_period_arraylike(index):
raise TypeError("PeriodIndex given. Check the `freq` attribute "
"instead of using infer_freq.")
"instead of using infer_freq.")
if isinstance(index, pd.Index) and not isinstance(index, pd.DatetimeIndex):
if isinstance(index, (pd.Int64Index, pd.Float64Index)):
raise TypeError("cannot infer freq from a non-convertible index type {0}".format(type(index)))
Expand Down
4 changes: 4 additions & 0 deletions pandas/tseries/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,10 @@ def __contains__(self, key):
def _box_func(self):
return lambda x: Period._from_ordinal(ordinal=x, freq=self.freq)

def _to_embed(self, keep_tz=False):
""" return an array repr of this object, potentially casting to object """
return self.asobject.values

def asof_locs(self, where, mask):
"""
where : array of timestamps
Expand Down