【问题标题】:Is it possible to do multiple different concatenates with one call?是否可以一次调用多个不同的连接?
【发布时间】:2020-07-14 17:08:22
【问题描述】:

我有 3 个独立的 numpy.array 并且需要在一个循环中将它们与另外 3 个连接数千次。为了性能起见,我想知道是否有某种方法可以通过一个 numpy.concatenate() 调用来完成这 3 个连接。

现在我有:

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]]

【问题讨论】:

  • 您能否确认,如果您的所有输入数组都是形状 (3,),您希望 arr 是什么形状?
  • 如果您正在寻找优化,也许您应该考虑将循环重写为矢量化操作。 Python 在循环中真的很慢。您可能想在这里分享更多代码。
  • 不要在循环中重复concatenateconcatenate 获取数组列表np.concatenate([arr1_1, arr1_2, arr1_3, ...])。构建该列表(附加列表),并在最后执行一个concatenate
  • 请提供预期的输入和输出示例

标签: python numpy concatenation


【解决方案1】:

当您不重新分配内存时,优化是最好的。

因此,您应该为循环中需要执行的所有操作设置一个或多个数组。如果您可以将所需的所有内容放入一个大数组中,您甚至可能不需要进行连接操作。

这是一个技术示例

# 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])

请注意,当您使用[:] 之类的索引进行赋值时,它不会创建新数组。相反,它将值分配给现有数组。这应该更快(我没有检查),因为它不需要在每个循环中分配新的内存。

【讨论】:

  • 谢谢!我不知道 [:] 的那种分配。不过,在我的代码中,我不知道最终的数组长度。使用预分配进行操作将是启发式的。
  • 在这种情况下,您最好在无限循环中使用列表或数组列表。尽管它们的内存效率较低,但它们速度很快。
【解决方案2】:

最后我遵循了这个建议:

当您不重新分配内存时,优化是最好的。

所以你应该为你需要做的每一件事设置一个或多个数组 循环内。如果你能把你需要的一切都放在一个大阵列中 您甚至可能不需要进行连接操作。

我启发式地将数组预分配给最坏的情况,而不是连接它们,而是从时间数组中复制值。通过这种方法,我实现了性能翻倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2023-02-11
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多