Reputation: 116820
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
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