ENH: Series.align method to leverage faster joins, faster binary ops · pandas-dev/pandas@56e0c9f (original) (raw)
`@@ -41,11 +41,10 @@ def wrapper(self, other):
`
41
41
`if self.index.equals(other.index):
`
42
42
`return Series(op(self.values, other.values), index=self.index)
`
43
43
``
44
``
`-
new_index = self.index + other.index
`
45
``
`-
this_reindexed = self.reindex(new_index)
`
46
``
`-
other_reindexed = other.reindex(new_index)
`
``
44
`+
this_reindexed, other_reindexed = self.align(other, join='outer',
`
``
45
`+
copy=False)
`
47
46
`arr = op(this_reindexed.values, other_reindexed.values)
`
48
``
`-
return Series(arr, index=new_index)
`
``
47
`+
return Series(arr, index=this_reindexed.index)
`
49
48
`elif isinstance(other, DataFrame):
`
50
49
`return NotImplemented
`
51
50
`else:
`
`@@ -955,9 +954,8 @@ def _binop(self, other, func, fill_value=None):
`
955
954
`this = self
`
956
955
``
957
956
`if not self.index.equals(other.index):
`
958
``
`-
new_index = self.index + other.index
`
959
``
`-
this = self.reindex(new_index)
`
960
``
`-
other = other.reindex(new_index)
`
``
957
`+
this, other = self.align(other, join='outer')
`
``
958
`+
new_index = this.index
`
961
959
``
962
960
`this_vals = this.values
`
963
961
`other_vals = other.values
`
`@@ -1265,6 +1263,43 @@ def apply(self, func):
`
1265
1263
`except Exception:
`
1266
1264
`return Series([func(x) for x in self], index=self.index)
`
1267
1265
``
``
1266
`+
def align(self, other, join='outer', copy=True):
`
``
1267
`+
"""
`
``
1268
`+
Align two Series object with the specified join method
`
``
1269
+
``
1270
`+
Parameters
`
``
1271
`+
`
``
1272
`+
other : Series
`
``
1273
`+
join : {'outer', 'inner', 'left', 'right'}, default 'outer'
`
``
1274
+
``
1275
`+
Returns
`
``
1276
`+
`
``
1277
`+
(left, right) : (Series, Series)
`
``
1278
`+
Aligned Series
`
``
1279
`+
"""
`
``
1280
`+
join_index, lidx, ridx = self.index.join(other.index, how=join,
`
``
1281
`+
return_indexers=True)
`
``
1282
+
``
1283
`+
if lidx is not None:
`
``
1284
`+
left = Series(common.take_1d(self.values, lidx), join_index)
`
``
1285
`+
else:
`
``
1286
`+
if copy:
`
``
1287
`+
new_values = self.values.copy()
`
``
1288
`+
else:
`
``
1289
`+
new_values = self.values
`
``
1290
`+
left = Series(new_values, join_index)
`
``
1291
+
``
1292
`+
if ridx is not None:
`
``
1293
`+
right = Series(common.take_1d(other.values, ridx), join_index)
`
``
1294
`+
else:
`
``
1295
`+
if copy:
`
``
1296
`+
new_values = other.values.copy()
`
``
1297
`+
else:
`
``
1298
`+
new_values = other.values
`
``
1299
`+
right = Series(new_values, join_index)
`
``
1300
+
``
1301
`+
return left, right
`
``
1302
+
1268
1303
`def reindex(self, index=None, method=None, copy=True):
`
1269
1304
`"""Conform Series to new index with optional filling logic, placing
`
1270
1305
` NA/NaN in locations having no value in the previous index. A new object
`