Разделение Python numpy с индексами

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

Я ищу numpy-эквивалент моего неоптимального кода Python. Вычисление, которое я хочу сделать, можно суммировать следующим образом:

Среднее значение пика каждой секции для каждой строки.

Вот код с образцом массива и списком индексов. Разделы могут быть разных размеров.

 x = np.array([[1, 2, 3, 4],
              [5, 6, 7, 8]])
indices = [2]
result = np.empty((1, x.shape[0]))
for row in x:
    splited = np.array_split(row, indexes)
    peak = [np.amax(a) for a in splited]
    result[0, i] = np.average(peak)
 

Что дает: result = array([[3., 7.]])

Каков оптимизированный numpy-способ подавления обоих циклов?

Ответ №1:

Вы могли бы просто снять for цикл и использовать axis вместо:

 result2 = np.mean([np.max(arr, 1) for arr in np.array_split(x_large, indices, 1)], axis=0)
 

Вывод:

 array([3., 7.])
 

Бенчмарк:

 x_large = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8]] * 1000)
%%timeit
result = []
for row in x_large:
    splited = np.array_split(row, indices)
    peak = [np.amax(a) for a in splited]
    result.append(np.average(peak))

# 29.9 ms ± 177 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit np.mean([np.max(arr, 1) for arr in np.array_split(x_large, indices, 1)], axis=0)

# 37.4 µs ± 499 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
 

Валидация:

 np.array_equal(result, result2)
# True
 

Комментарии:

1. Существует проблема, когда разделы не имеют одинакового размера. x = np.array([[1, 2, 3, 4, 4], [5, 6, 7, 8, 8]]) должен дать тот же результат, но сбой с «ValueError: не удалось передать входной массив из формы (2,2) в форму (2)»

2. @Jordan Я обновил версию для понимания списка. Можете ли вы попробовать ;)?