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

`