Разделите ndarray по максимумам по заданной оси - PullRequest
0 голосов
/ 02 марта 2019

Скажем, у меня есть такой массив

import numpy as np

a = np.array([[2]*9 + [3]*9 + [4]*9])
a = a.reshape((-1,3, 3))
print(a)

Что составляет

[[[2 2 2]
  [2 2 2]
  [2 2 2]]

 [[3 3 3]
  [3 3 3]
  [3 3 3]]

 [[4 4 4]
  [4 4 4]
  [4 4 4]]]

Так, например, если я хочу разделить каждый объект по оси 0 на его максимальное значение (дляполучить только 1), как бы я сделал это без зацикливания?

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Основываясь на приведенном выше ответе, я подумал, что было бы полезно распространить его на преобразования, требующие более одной простой функции, например, нормализация в [0,1] с использованием min / max:

import numpy as np
np.random.seed(1)

def zero_one_normalize_3d(arr):
    fs = np.min, np.max
    arr_min, arr_max = [f(arr, axis = (1, 2), keepdims = True) for f in fs]
    return (arr - arr_min) / (arr_max - arr_min)

def zero_one_normalize_2d(arr):
    return (arr - arr.min()) / (arr.max() - arr.min())

points = 10000
x1 = np.random.normal(3, 10, points)
x2 = np.random.normal(6, 10, points)
x3 = np.random.normal(9, 10, points)
a = np.column_stack((x1, x2, x3))
a = a.reshape(-1, 10, 3)

print(np.alltrue(zero_one_normalize_3d(a)[0] == zero_one_normalize_2d(a[0])))
> True
0 голосов
/ 02 марта 2019

Вы можете найти максимальное значение в каждом ndarray по первой оси, взяв np.max вдоль их строк и столбцов, установив keepdims=True, так что a делится на результирующий максимумзначения по первой оси:

a / np.max(a, axis=(1,2), keepdims=True)

Выход

array([[[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]],

       [[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]],

       [[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]]])
...