Skip to content

Commit 6dcc238

Browse files
BUG: fix alignment in series ops (GH14227) (#14230)
* BUG: fix alignment in series ops (GH14227) * BUG: fix align in case of different tz but aligning values
1 parent ad92aee commit 6dcc238

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

pandas/core/generic.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
is_numeric_dtype,
2121
is_datetime64_dtype,
2222
is_timedelta64_dtype,
23+
is_datetime64tz_dtype,
2324
is_list_like,
2425
is_dict_like,
2526
is_re_compilable)
@@ -4438,13 +4439,23 @@ def _align_frame(self, other, join='outer', axis=None, level=None,
44384439
left = left.fillna(axis=fill_axis, method=method, limit=limit)
44394440
right = right.fillna(axis=fill_axis, method=method, limit=limit)
44404441

4442+
# if DatetimeIndex have different tz, convert to UTC
4443+
if is_datetime64tz_dtype(left.index):
4444+
if left.index.tz != right.index.tz:
4445+
if join_index is not None:
4446+
left.index = join_index
4447+
right.index = join_index
4448+
44414449
return left.__finalize__(self), right.__finalize__(other)
44424450

44434451
def _align_series(self, other, join='outer', axis=None, level=None,
44444452
copy=True, fill_value=None, method=None, limit=None,
44454453
fill_axis=0):
4454+
4455+
is_series = isinstance(self, ABCSeries)
4456+
44464457
# series/series compat, other must always be a Series
4447-
if isinstance(self, ABCSeries):
4458+
if is_series:
44484459
if axis:
44494460
raise ValueError('cannot align series to a series other than '
44504461
'axis 0')
@@ -4503,6 +4514,15 @@ def _align_series(self, other, join='outer', axis=None, level=None,
45034514
left = left.fillna(fill_value, method=method, limit=limit,
45044515
axis=fill_axis)
45054516
right = right.fillna(fill_value, method=method, limit=limit)
4517+
4518+
# if DatetimeIndex have different tz, convert to UTC
4519+
if is_series or (not is_series and axis == 0):
4520+
if is_datetime64tz_dtype(left.index):
4521+
if left.index.tz != right.index.tz:
4522+
if join_index is not None:
4523+
left.index = join_index
4524+
right.index = join_index
4525+
45064526
return left.__finalize__(self), right.__finalize__(other)
45074527

45084528
def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,

pandas/core/ops.py

-6
Original file line numberDiff line numberDiff line change
@@ -622,12 +622,6 @@ def _align_method_SERIES(left, right, align_asobject=False):
622622

623623
left, right = left.align(right, copy=False)
624624

625-
index, lidx, ridx = left.index.join(right.index, how='outer',
626-
return_indexers=True)
627-
# if DatetimeIndex have different tz, convert to UTC
628-
left.index = index
629-
right.index = index
630-
631625
return left, right
632626

633627

pandas/tests/series/test_operators.py

+8
Original file line numberDiff line numberDiff line change
@@ -1810,3 +1810,11 @@ def test_dti_tz_convert_to_utc(self):
18101810

18111811
res = Series([1, 2], index=idx1) + Series([1, 1], index=idx2)
18121812
assert_series_equal(res, Series([np.nan, 3, np.nan], index=base))
1813+
1814+
def test_op_duplicate_index(self):
1815+
# GH14227
1816+
s1 = Series([1, 2], index=[1, 1])
1817+
s2 = Series([10, 10], index=[1, 2])
1818+
result = s1 + s2
1819+
expected = pd.Series([11, 12, np.nan], index=[1, 1, 2])
1820+
assert_series_equal(result, expected)

pandas/tseries/tests/test_timezones.py

+22
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,28 @@ def test_align_aware(self):
12901290
self.assertEqual(df1.index.tz, new1.index.tz)
12911291
self.assertEqual(df2.index.tz, new2.index.tz)
12921292

1293+
# # different timezones convert to UTC
1294+
1295+
# frame
1296+
df1_central = df1.tz_convert('US/Central')
1297+
new1, new2 = df1.align(df1_central)
1298+
self.assertEqual(new1.index.tz, pytz.UTC)
1299+
self.assertEqual(new2.index.tz, pytz.UTC)
1300+
1301+
# series
1302+
new1, new2 = df1[0].align(df1_central[0])
1303+
self.assertEqual(new1.index.tz, pytz.UTC)
1304+
self.assertEqual(new2.index.tz, pytz.UTC)
1305+
1306+
# combination
1307+
new1, new2 = df1.align(df1_central[0], axis=0)
1308+
self.assertEqual(new1.index.tz, pytz.UTC)
1309+
self.assertEqual(new2.index.tz, pytz.UTC)
1310+
1311+
df1[0].align(df1_central, axis=0)
1312+
self.assertEqual(new1.index.tz, pytz.UTC)
1313+
self.assertEqual(new2.index.tz, pytz.UTC)
1314+
12931315
def test_append_aware(self):
12941316
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H',
12951317
tz='US/Eastern')

0 commit comments

Comments
 (0)