Как применить функцию к неровным массивам Numpy (неравной длины строк) без использования np.apply_along_axis ()? - PullRequest
0 голосов
/ 26 сентября 2019

Я пытаюсь ускорить процесс, я думаю, что это возможно, используя apply_along_axis от numpy.Проблема в том, что не все мои оси имеют одинаковую длину.

Когда я делаю:

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

Это работает нормально.Но я хотел бы сделать что-то похожее на (обратите внимание, что в первой строке 4 элемента, а в остальных 3) :

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

Но это не удается, потому что:

numpy.AxisError: ось 1 выходит за границы для массива измерения 1

Я посмотрел вокруг, и единственное найденное «решение» - это добавить нули, чтобы сделатьвсе массивы одинаковой длины, что, вероятно, не позволило бы улучшить производительность.

Есть ли способ использовать numpy_apply_along_axis для массива numpy нерегулярной формы?

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Это зависит.Вы знаете размер векторов раньше или добавляете их в список?

см., Например, http://stackoverflow.com/a/58085045/7919597

Вы можете, например, заполнить массивы

import numpy as np

a1 = [1, 2, 3, 4]
a2 = [2, 3, 4, np.nan] # pad with nan
a3 = [4, 5, 6, np.nan] # pad with nan

b = np.stack([a1, a2, a3], axis=0)

print(b)

# you can apply the normal numpy operations on 
# arrays with nan, they usually just result in a nan
# in a resulting array
c = np.diff(b, axis=-1)

print(c)

После этого вы можете применить движущееся окно к каждой строке над столбцами.

Взгляните на https://stackoverflow.com/a/22621523/7919597, который является только 1d, но может дать вам представление о том, как он может работать.

Можно использовать 2d-массив с одной строкой в ​​качестве ядра(форма например (1, 3)) с scipy.signal.convolve2d и использовать идею выше.Это обходной путь для получения «рядовой 1-мерной свертки»:

from scipy import signal

krnl = np.array([[0, 1, 0]])

d = signal.convolve2d(c, krnl, mode='same')
print(d)
1 голос
/ 26 сентября 2019

Вы можете преобразовать исходный массив итерируемых объектов в ndarray, заполнив их нулями векторизованным способом:

import numpy as np

a = np.array([[1, 2, 3, 4], 
              [2, 3, 4], 
              [4, 5, 6]])
max_len = len(max(a, key = lambda x: len(x))) # max length of iterable-objects contained in array
cust_func = np.vectorize(pyfunc=lambda x: np.pad(array=x, 
                                                 pad_width=(0,max_len), 
                                                 mode='constant', 
                                                 constant_values=(0,0))[:max_len], otypes=[list])
a_pad = np.stack(cust_func(a))

output:

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