Skip to content

Commit e898890

Browse files
TomAugspurgerPingviinituutti
authored andcommitted
BUG: Allow freq conversion from dt64 to period (pandas-dev#23460)
Closes pandas-dev#23438
1 parent 1e71775 commit e898890

File tree

3 files changed

+28
-19
lines changed

3 files changed

+28
-19
lines changed

pandas/core/arrays/period.py

+7-16
Original file line numberDiff line numberDiff line change
@@ -967,24 +967,15 @@ def dt64arr_to_periodarr(data, freq, tz=None):
967967
if data.dtype != np.dtype('M8[ns]'):
968968
raise ValueError('Wrong dtype: %s' % data.dtype)
969969

970-
if freq is not None:
971-
freq = Period._maybe_convert_freq(freq)
970+
if freq is None:
971+
if isinstance(data, ABCIndexClass):
972+
data, freq = data._values, data.freq
973+
elif isinstance(data, ABCSeries):
974+
data, freq = data._values, data.dt.freq
972975

973-
if isinstance(data, ABCIndexClass):
974-
if freq is None:
975-
freq = data.freq
976-
elif freq != data.freq:
977-
msg = DIFFERENT_FREQ_INDEX.format(freq.freqstr, data.freq.freqstr)
978-
raise IncompatibleFrequency(msg)
979-
data = data._values
976+
freq = Period._maybe_convert_freq(freq)
980977

981-
elif isinstance(data, ABCSeries):
982-
if freq is None:
983-
freq = data.dt.freq
984-
elif freq != data.dt.freq:
985-
msg = DIFFERENT_FREQ_INDEX.format(freq.freqstr,
986-
data.dt.freq.freqstr)
987-
raise IncompatibleFrequency(msg)
978+
if isinstance(data, (ABCIndexClass, ABCSeries)):
988979
data = data._values
989980

990981
base, mult = frequencies.get_freq_code(freq)

pandas/tests/arrays/test_period.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ def test_period_array_ok(data, freq, expected):
3434
tm.assert_numpy_array_equal(result, expected)
3535

3636

37-
def test_from_datetime64_raises():
37+
def test_from_datetime64_freq_changes():
38+
# https://github.com/pandas-dev/pandas/issues/23438
3839
arr = pd.date_range("2017", periods=3, freq="D")
39-
with tm.assert_raises_regex(IncompatibleFrequency, "freq"):
40-
PeriodArray._from_datetime64(arr, freq="M")
40+
result = PeriodArray._from_datetime64(arr, freq="M")
41+
expected = period_array(['2017-01-01', '2017-01-01', '2017-01-01'],
42+
freq="M")
43+
tm.assert_period_array_equal(result, expected)
4144

4245

4346
@pytest.mark.parametrize("data, freq, msg", [

pandas/tests/indexes/period/test_construction.py

+15
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,21 @@ def test_constructor_datetime64arr(self):
158158

159159
pytest.raises(ValueError, PeriodIndex, vals, freq='D')
160160

161+
@pytest.mark.parametrize('box', [None, 'series', 'index'])
162+
def test_constructor_datetime64arr_ok(self, box):
163+
# https://github.com/pandas-dev/pandas/issues/23438
164+
data = pd.date_range('2017', periods=4, freq="M")
165+
if box is None:
166+
data = data._values
167+
elif box == 'series':
168+
data = pd.Series(data)
169+
170+
result = PeriodIndex(data, freq='D')
171+
expected = PeriodIndex([
172+
'2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30'
173+
], freq="D")
174+
tm.assert_index_equal(result, expected)
175+
161176
def test_constructor_dtype(self):
162177
# passing a dtype with a tz should localize
163178
idx = PeriodIndex(['2013-01', '2013-03'], dtype='period[M]')

0 commit comments

Comments
 (0)