Можно ли сделать несколько разных объединений одним вызовом? - PullRequest
2 голосов
/ 02 апреля 2020

У меня есть 3 независимых numpy .array, и мне нужно объединить их с другими 3 в течение oop тысяч раз. Ради производительности я хотел бы знать, есть ли какой-нибудь способ выполнить эти 3 объединения только с одним вызовом numpy .concatenate ().

Сейчас у меня есть:

arr1 = np.concatenate([arr1, _arr1])
arr2 = np.concatenate([arr2, _arr2])
arr3 = np.concatenate([arr3, _arr3])

И я хотел бы получить тот же результат всего одним вызовом, например:

arr = [arr1, arr2, arr3]
_arr = [_arr1, _arr2, _arr3]
arr = np.concatenate([arr, _arr])

Возможно ли это как-нибудь? Если нет, то какой будет наилучший подход?

Пример ввода и желаемого выхода:

#Inputs
arr1 = [1,2]
arr2 = [3,4]
arr3 = [5,6]
_arr1 = [-1,-2]
_arr2 = [-3,-4]
_arr3 = [-5,-6]
#Output
arr = [[1,2,-1,-2], [3,4,-3,-4], [5,6,-5,-6]]

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Оптимизация лучше всего, когда вы не перераспределяете память.

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

Вот пример метода

# Declare one array for all data
data = np.zeros((3,6))

# Define sub-arrays
arr1 = data[0,:3]
_arr1 = data[0,3:]
arr2 = data[1,:3]
_arr2 = data[1,3:]
arr3 = data[2,:3]
_arr3 = data[2,3:]

for i in range(5):

    # New values from somewhere
    arr1[:] = np.random.randn(3)                                                      
    arr2[:] = np.random.randn(3)                                                      
    arr3[:] = np.random.randn(3)                                                     
    _arr1[:] = np.random.randn(3)
    _arr2[:] = np.random.randn(3)
    _arr3[:] = np.random.randn(3)

    # Combined arrays
    print(data[0])  # same as np.concatenate([arr1, _arr1])
    print(data[1])  # same as np.concatenate([arr2, _arr2])
    print(data[2])  # same as np.concatenate([arr3, _arr3])

Обратите внимание, что при выполнении назначения с индекс типа [:] не создает новый массив. Вместо этого он присваивает значения существующему массиву. Это должно быть быстрее (я не проверял), так как ему не нужно выделять новую память каждый l oop.

0 голосов
/ 07 апреля 2020

В конце концов я последовал этому совету:

Оптимизация лучше всего, когда вы не перераспределяете память.

Таким образом, вы должны настроить один или несколько массивов для все, что вам нужно сделать в пределах l oop. Если вы можете собрать все необходимое в один большой массив, вам, возможно, даже не потребуется выполнять операцию конкатенации.

Я предварительно выделяю массивы эвристически в худшем случае, и вместо того, чтобы объединить их, я копирую значения из временных массивов. Благодаря такому подходу я смог удвоить производительность.

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