Нулевой массив numpy

Какой более питонический способ заполнить массив нулями в конце?

def pad(A, length):
    ...

A = np.array([1,2,3,4,5])
pad(A, 8)    # expected : [1,2,3,4,5,0,0,0]

В моем реальном случае использования на самом деле я хочу дополнить массив ближайшим числом, кратным 1024. Например: 1342 => 2048, 3000 => 3072.


person Basj    schedule 04.07.2016    source источник


Ответы (6)


В вашем случае вы можете использовать resize () метод:

A = np.array([1,2,3,4,5])
A.resize(8)

Это изменяет размер A на месте. Если есть ссылки на A, numpy выдает ошибку vale, потому что ссылочное значение также будет обновлено. Чтобы разрешить это, добавьте опцию refcheck=False.

В документации указано, что отсутствующие значения будут 0:

Увеличение массива: аналогично предыдущему, но недостающие элементы заполняются нулями

person thespinkus    schedule 15.03.2021
comment
Спасибо @semisecure! Наконец-то очень простое решение спустя 4 года :) - person Basj; 15.03.2021

numpy.pad с режимом constant делает то, что вам нужно, где мы можем передать кортеж в качестве второго аргумента, чтобы указать, сколько нулей нужно заполнить для каждого размера, например, (2, 3) добавит 2 нуля слева и < strong>3 нуля справа:

Дан A как:

A = np.array([1,2,3,4,5])

np.pad(A, (2, 3), 'constant')
# array([0, 0, 1, 2, 3, 4, 5, 0, 0, 0])

Также возможно заполнить массивы 2D numpy, передав кортеж кортежей в качестве ширины заполнения, который принимает формат ((top, bottom), (left, right)):

A = np.array([[1,2],[3,4]])

np.pad(A, ((1,2),(2,1)), 'constant')

#array([[0, 0, 0, 0, 0],           # 1 zero padded to the top
#       [0, 0, 1, 2, 0],           # 2 zeros padded to the bottom
#       [0, 0, 3, 4, 0],           # 2 zeros padded to the left
#       [0, 0, 0, 0, 0],           # 1 zero padded to the right
#       [0, 0, 0, 0, 0]])

В вашем случае вы указываете, что левая сторона равна нулю, а правая сторона вычисляется из модульного деления:

B = np.pad(A, (0, 1024 - len(A)%1024), 'constant')
B
# array([1, 2, 3, ..., 0, 0, 0])
len(B)
# 1024

Для большего A:

A = np.ones(3000)
B = np.pad(A, (0, 1024 - len(A)%1024), 'constant')
B
# array([ 1.,  1.,  1., ...,  0.,  0.,  0.])

len(B)
# 3072
person Psidom    schedule 04.07.2016
comment
Спасибо! Это работает, если исходная длина 3000? (тогда дополненная длина должна быть 3072) - person Basj; 04.07.2016
comment
Так и должно быть, поскольку правильная длина заполнения здесь — это разница между 1024 и модульным остатком от len(A), деленная на 1024. Это должно быть легко проверить. - person Psidom; 04.07.2016
comment
что, если у меня есть 3D-том для заполнения? - person Rishabh Agrahari; 18.03.2018
comment
Это действительно самый яркий пример, который я когда-либо видел. Спасибо!! - person Allan Ruin; 18.03.2019
comment
это не работает для меня, и я не понимаю, почему -1d" title="numpy pad с нулями создает массив 2d вместо желаемого 1d"> stackoverflow.com/questions/56413710/ - person Gulzar; 02.06.2019
comment
mode='constant' — это значение по умолчанию, его не нужно указывать напрямую. Документы: numpy.org/doc/stable/reference/generated/numpy. pad.html - person Adam; 31.07.2020

Для дальнейшего использования:

def padarray(A, size):
    t = size - len(A)
    return np.pad(A, pad_width=(0, t), mode='constant')

padarray([1,2,3], 8)     # [1 2 3 0 0 0 0 0]
person Basj    schedule 28.12.2016

Это должно работать:

def pad(A, length):
    arr = np.zeros(length)
    arr[:len(A)] = A
    return arr

Вы можете получить немного лучшую производительность, если инициализируете пустой массив (np.empty(length)), а затем заполните A и zeros по отдельности, но я сомневаюсь, что в большинстве случаев ускорение стоило бы дополнительной сложности кода. .

Чтобы получить значение для заполнения, я думаю, вы, вероятно, просто использовали бы что-то вроде divmod:

n, remainder = divmod(len(A), 1024)
n += bool(remainder)

По сути, это просто вычисляет, сколько раз 1024 делит длину вашего массива (и каков остаток от этого деления). Если остатка нет, то вам просто нужны n * 1024 элементов. Если есть остаток, то вам нужно (n + 1) * 1024.

все вместе:

def pad1024(A):
    n, remainder = divmod(len(A), 1024)
    n += bool(remainder)
    arr = np.zeros(n * 1024)
    arr[:len(A)] = A
    return arr        
person mgilson    schedule 04.07.2016
comment
Спасибо! Любая идея для автоматического заполнения, чтобы сделать длину кратной 1024? Я что-то пишу, но это очень не питонично;) - person Basj; 04.07.2016
comment
@Basj -- Конечно, проверьте мое обновление. Я не проверял это или что-то еще, но я думаю, что это должно работать... - person mgilson; 04.07.2016
comment
Это то, что делает pad, но с большим количеством наворотов (спереди, сзади, разные оси, другие режимы заполнения). - person hpaulj; 05.07.2016

Вы также можете использовать numpy.pad:

>>> A = np.array([1,2,3,4,5])
>>> npad = 8 - len(A)
>>> np.pad(A, pad_width=npad, mode='constant', constant_values=0)[npad:]
array([1, 2, 3, 4, 5, 0, 0, 0])

И в функции:

def pad(A, npads):
    _npads = npads - len(A)
    return np.pad(A, pad_width=_npads, mode='constant', constant_values=0)[_npads:]
person Moses Koledoye    schedule 04.07.2016

Есть np.pad:

A = np.array([1, 2, 3, 4, 5])
A = np.pad(A, (0, length), mode='constant')

Что касается вашего варианта использования, необходимое количество нулей для заполнения можно рассчитать как length = len(A) + 1024 - 1024 % len(A).

person lballes    schedule 04.07.2016