Как применить редуктор по нескольким осям? - PullRequest
0 голосов
/ 20 июня 2020

Я, вероятно, смогу реализовать это сам, но я бы предпочел не изобретать никаких колес.

Учитывая ndarray, я хотел бы применить пользовательскую функцию к каждому элементу некоторой случайной оси.

Самый простой пример c - применение функции к строкам или столбцам массива 2darray.

Более сложный пример - применение функции к каждой ячейке 3 на 4 ячейке массива 10x20x3x4 ndarray. Это означало бы, что я применяю функцию к осям 2 и 3 (подсчет на основе 0).

Еще более сложным примером может быть применение функции к каждой ячейке 5 на 3 на 4 ячейке из массива Ax5xBxCx3xEx4xF ndarray. Это будет означать, что я применяю функцию к осям 1, 4 и 6.

Я уверен, что эта функция должна быть скрыта где-то в numpy или, может быть, даже basi c python, но Я просто недостаточно разбираюсь в Python, чтобы знать, с чего начать.

Похоже, numpy .ufun c .reduce, возможно, делает то, что я хочу, за исключением того, что он работает только для ufuncs, а не для пользовательских функций.

1 Ответ

0 голосов
/ 20 июня 2020

Вы по-прежнему можете использовать numpy.ufunc.reduce с пользовательской функцией, используя numpy.frompyfunc. Просто сделайте что-то вроде этого:

#Example function
def does_it_halt(f, will_the_universe_ever_end):
  if will_the_universe_ever_end:
    return True
  else:
    does_it_halt(f)

# Creates a ufunc given the function object, the number of inputs, and the number of outputs
my_ufunc = numpy.frompyfunc(func=does_it_halt, nin=2, nout=1)

Тогда вы можете использовать это примерно так:

arr = np.arange(24).reshape((2, 3, 4))

>>> array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

#Group multiple axes
new_arr = np.concatenate([arr[0], arr[1]])

>>> array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])

single_dim = new_arr.reshape(24)
>>> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

# And finally reduce it
np.add.reduce(single_dim)
>>> 276
...