Legend
Legend

Reputation: 116820

How can I apply a function one column at a time?

I have a numpy datastructure as follows:

[[['diaad'],
  ['iaadf'],
  ['aadfe'],
  ['hedbb'],
  ['edbbb'],
  ['dbbbb']],

 [['gegec'],
  ['ehecf'],
  ['gecfc'],
  ['gadff'],
  ['adfef'],
  ['dffgc']],

 [['ddddj'],
  ['dddjd'],
  ['ddjdd'],
  ['jfffd'],
  ['fgfdb'],
  ['ggdbb']]]

which is instantiated like this:

>>> a = np.array([[['diaad'], ['iaadf'],  ['aadfe'],  ['hedbb'],  ['edbbb'],  ['dbbbb']], [['gegec'],  ['ehecf'],  ['gecfc'],  ['gadff'],  ['adfef'],  ['dffgc']], [['ddddj'],  ['dddjd'],  ['ddjdd'],  ['jfffd'],  ['fgfdb'],  ['ggdbb']]])

Is there a direct numpy way of computing a custom function over pairwise elements?

For instance, say, my custom function is called processPair(a,b). It should compute the result for all pairwise elements along the column i.e. between ('diaad', 'gegec'), ('gegec', 'ddddj') and ('diaad', 'ddddj'). Any suggestions on doing this? I was thinking the map function can achieve this but am not entirely sure how though.

Upvotes: 0

Views: 162

Answers (1)

Lauritz V. Thaulow
Lauritz V. Thaulow

Reputation: 50995

Here's my solution. I'm not entirely pleased with it -- I feel like it should be possible to do it more elegantly -- but it works:

from itertools import combinations

def apply_pairwise(func, a):
    "For each row, call func with every possible combination of two values"

    stack = []
    for col_a, col_b in combinations(range(a.shape[0]), 2):
        stack.append(np.hstack([a[col_a], a[col_b]]))

    combined = np.vstack(stack)

    def unpack_row(row):
        "Calls func with the values of a given numpy array as arguments"
        return func(*row.tolist())

    return np.apply_along_axis(unpack_row, 1, combined)

Use like this (assuming your example array a has been defined):

>>> f = lambda x, y: x + y
>>> print apply_pairwise(f, a)
['diaadgegec' 'iaadfehecf' 'aadfegecfc' 'hedbbgadff' 'edbbbadfef'
'dbbbbdffgc' 'diaadddddj' 'iaadfdddjd' 'aadfeddjdd' 'hedbbjfffd'
'edbbbfgfdb' 'dbbbbggdbb' 'gegecddddj' 'ehecfdddjd' 'gecfcddjdd'
'gadffjfffd' 'adfeffgfdb' 'dffgcggdbb']

Upvotes: 1

Related Questions