Skip to content

Commit 2cd85ca

Browse files
alanbatoTomAugspurger
authored andcommitted
Support non unique period indexes on join and merge operations (#16949)
* Support non unique period indexes on join and merge operations * Add frame assertion on tests and release notes * Explicitly use dtype int64 on arange
1 parent 96168ef commit 2cd85ca

File tree

4 files changed

+27
-3
lines changed

4 files changed

+27
-3
lines changed

doc/source/whatsnew/v0.21.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ Sparse
184184

185185
Reshaping
186186
^^^^^^^^^
187-
187+
- Joining/Merging with a non unique ``PeriodIndex`` raised a TypeError (:issue:`16871`)
188188

189189

190190
Numeric

pandas/core/indexes/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3119,14 +3119,14 @@ def _join_multi(self, other, how, return_indexers=True):
31193119
def _join_non_unique(self, other, how='left', return_indexers=False):
31203120
from pandas.core.reshape.merge import _get_join_indexers
31213121

3122-
left_idx, right_idx = _get_join_indexers([self.values],
3122+
left_idx, right_idx = _get_join_indexers([self._values],
31233123
[other._values], how=how,
31243124
sort=True)
31253125

31263126
left_idx = _ensure_platform_int(left_idx)
31273127
right_idx = _ensure_platform_int(right_idx)
31283128

3129-
join_index = np.asarray(self.values.take(left_idx))
3129+
join_index = np.asarray(self._values.take(left_idx))
31303130
mask = left_idx == -1
31313131
np.putmask(join_index, mask, other._values.take(right_idx))
31323132

pandas/tests/reshape/test_join.py

+12
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,18 @@ def test_join_mixed_non_unique_index(self):
550550
index=[1, 2, 2, 'a'])
551551
tm.assert_frame_equal(result, expected)
552552

553+
def test_join_non_unique_period_index(self):
554+
# GH #16871
555+
index = pd.period_range('2016-01-01', periods=16, freq='M')
556+
df = DataFrame([i for i in range(len(index))],
557+
index=index, columns=['pnum'])
558+
df2 = concat([df, df])
559+
result = df.join(df2, how='inner', rsuffix='_df2')
560+
expected = DataFrame(
561+
np.tile(np.arange(16, dtype=np.int64).repeat(2).reshape(-1, 1), 2),
562+
columns=['pnum', 'pnum_df2'], index=df2.sort_index().index)
563+
tm.assert_frame_equal(result, expected)
564+
553565
def test_mixed_type_join_with_suffix(self):
554566
# GH #916
555567
df = DataFrame(np.random.randn(20, 6),

pandas/tests/reshape/test_merge.py

+12
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,18 @@ def test_merge_on_datetime64tz(self):
585585
assert result['value_x'].dtype == 'datetime64[ns, US/Eastern]'
586586
assert result['value_y'].dtype == 'datetime64[ns, US/Eastern]'
587587

588+
def test_merge_non_unique_period_index(self):
589+
# GH #16871
590+
index = pd.period_range('2016-01-01', periods=16, freq='M')
591+
df = DataFrame([i for i in range(len(index))],
592+
index=index, columns=['pnum'])
593+
df2 = concat([df, df])
594+
result = df.merge(df2, left_index=True, right_index=True, how='inner')
595+
expected = DataFrame(
596+
np.tile(np.arange(16, dtype=np.int64).repeat(2).reshape(-1, 1), 2),
597+
columns=['pnum_x', 'pnum_y'], index=df2.sort_index().index)
598+
tm.assert_frame_equal(result, expected)
599+
588600
def test_merge_on_periods(self):
589601
left = pd.DataFrame({'key': pd.period_range('20151010', periods=2,
590602
freq='D'),

0 commit comments

Comments
 (0)