I have the following data formats:
- type1 = np.array([...], dtype='float64') # vector of floats
- type2 = np.array([type1, type1, ...], dtype='object') # array of type 1
- type3 = np.array([type2, type2, ...], dtype='object') # array of type 2
(Just to focus the attention: type1 would be timeseries signal, and higher order types would constructed by splitting signal into smaller and smaller chunks of different sizes)
Now, I'd like to apply a function
(e.g. filtering) to each 1D vector (type) witch the following requirements:
- iterator accepts type1, type2 or type3 data and applies
function
to eachtype1
element. - it's possible to iterate over 2 arrays of the same dimensionality
- it's possible to extract additional info from iterator.
So the signature could be like:
out = apply([main_array, aux_array], function_to_apply, **kwargs)
with main_array
modified inside apply
Possible way to go, could be np.nditer like here: Vectorwise iteration of nD array with nditer however I haven't been able to create working solution yet. Any ideas?
EDIT: Thanks @JeromeRichards and @hpaulj for pointing right direction. I ended up with such recursive solution:
def zip_none(data, aux):
'''zip routine with none broadcasting'''
return zip(data, *aux) if aux is not None else zip(data)
def apply_1d(data, func, aux=None, **kwargs):
'''Apply `func` to each 1d vector in data. Params:
data - list of input data or np 1D array
aux - list of additional input data. Each element of aux should share dimensionality with data
func - function to be applied
kwargs - params to be passed to `func`'''
if isinstance(data, list):
result = []
multi_output = False
for x, *y in zip_none(data, aux):
aux = y if y else None
tmp = apply_1d(x, func, aux=aux, **kwargs)
result.append(tmp)
if isinstance(tmp, tuple):
multi_output = True
if multi_output:
result = tuple(list(out) for out in zip(*result))
else:
return func(data, *aux, **kwargs) if aux is not None else func(data, **kwargs)
return result