Укладка массивов Numpy разной длины с помощью заполнения - PullRequest
0 голосов
/ 29 октября 2018
a = np.array([1,2,3])
b = np.array([4,5])

l = [a,b]

Я хочу функцию stack_padding такую, что:

assert(stack_padding(l) == np.array([[1,2,3],[4,5,0]])

Есть ли стандартный способ достижения

РЕДАКТИРОВАТЬ: l может иметь потенциально гораздо больше элементов

Ответы [ 3 ]

0 голосов
/ 29 октября 2018

С numpy.pad:

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

l = [a,b]

max_len = max([len(arr) for arr in l])
padded = np.array([np.lib.pad(arr, (0, max_len - len(arr)), 'constant', constant_values=0) for arr in l])
0 голосов
/ 29 октября 2018

Если вы не хотите использовать itertools и column_stack, numpy.ndarray.resize также отлично справится с этой задачей. Как упомянуто jtweeder, вам просто нужно знать размер результирующих строк. Преимущество использования resize состоит в том, что numpy.ndarray является непрерывным в памяти. Изменение размера происходит быстрее, если каждая строка отличается по размеру. Разница в производительности наблюдается между двумя подходами.

import numpy as np
import timeit
import itertools

def stack_padding(it):

    def resize(row, size):
        new = np.array(row)
        new.resize(size)
        return new

    # find longest row length
    row_length = max(it, key=len).__len__()
    mat = np.array( [resize(row, row_length) for row in it] )

    return mat

def stack_padding1(l):
    return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))


if __name__ == "__main__":
    n_rows = 200
    row_lengths = np.random.randint(30, 50, size=n_rows)
    mat = [np.random.randint(0, 100, size=s) for s in row_lengths]

    def test_stack_padding():
        global mat
        stack_padding(mat)

    def test_itertools():
        global mat
        stack_padding1(mat)

    t1 = timeit.timeit(test_stack_padding, number=1000)
    t2 = timeit.timeit(test_itertools, number=1000)
    print('With ndarray.resize: ', t1)
    print('With itertool and vstack: ', t2)

Метод resize выигрывает в приведенном выше сравнении:

>>> With ndarray.resize:  0.30080295499647036
>>> With itertool and vstack:  1.0151802329928614
0 голосов
/ 29 октября 2018

Я думаю itertools.zip_longest с fill_value=0 может работать на вас:

import itertools

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

l = [a,b]

def stack_padding(l):
    return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))

>>> stack_padding(l)
array([[1, 2, 3],
       [4, 5, 0]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...