Замена значений, превышающих лимит в массиве numpy - PullRequest
4 голосов
/ 31 марта 2011

У меня есть массив nxm и максимальные значения для каждого столбца.Каков наилучший способ замены значений, превышающих максимум, помимо проверки каждого элемента?

Например:

def check_limits(bad_array, maxs):
    good_array = np.copy(bad_array)
    for i_line in xrange(bad_array.shape[0]):
        for i_column in xrange(bad_array.shape[1]):
            if good_array[i_line][i_column] >= maxs[i_column]:
                good_array[i_line][i_column] = maxs[i_column] - 1
    return good_array

В любом случае, сделать это быстрее и более кратко?

Ответы [ 4 ]

8 голосов
/ 31 марта 2011

Использование putmask :

import numpy as np

a = np.array([[ 0,  1,  2,  3],
              [ 4,  5,  6,  7],
              [ 8,  9, 10, 11]])
m = np.array([7,6,5,4])

# This is what you need:

np.putmask(a, a >= m, m - 1)

# a is now:

np.array([[0, 1, 2, 3],
          [4, 5, 4, 3],
          [6, 5, 4, 3]])
0 голосов
/ 30 января 2017

Другой способ - использовать функцию clip :

на примере eumiro:

bad_array = np.array([[ 0,  1,  2,  3],
                      [ 4,  5,  6,  7],
                      [ 8,  9, 10, 11]])
maxs = np.array([7,6,5,4])

good_array = bad_array.clip(max=maxs-1)

OR

bad_array.clip(max=maxs-1, out=good_array)

Вы также можете указать нижний предел, добавив аргумент min =

0 голосов
/ 31 марта 2011

Если количество столбцов не велико, одна оптимизация будет:

def check_limits(bad_array, maxs):
    good_array = np.copy(bad_array)
    for i_column in xrange(bad_array.shape[1]):
        to_replace = (good_array[:,i_column] >= maxs[i_column])
        good_array[to_replace, i_column] = maxs[i_column] - 1
    return good_array
0 голосов
/ 31 марта 2011

Если мы ничего не предполагаем о структуре bad_array, ваш код оптимален по аргументу противника. Если мы знаем, что каждый столбец отсортирован в порядке возрастания, то, как только мы достигнем значения, превышающего максимальное, мы узнаем, что каждый последующий элемент в этом столбце также выше предела, но если у нас нет такого предположения, мы просто имеем проверить каждый.

Если вы решите отсортировать каждый столбец первым, это займет (n столбцов * nlogn) время, которое уже больше, чем n * n времени, необходимого для проверки каждого элемента.

Вы также можете создать good_array, проверяя и копируя по одному элементу за раз, вместо копирования всех элементов из bad_array и проверки их позже. Это должно примерно сократить время в 0,5 раза

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...