【问题标题】:Append a numpy array with different first dimensions附加一个具有不同第一维的numpy数组
【发布时间】:2020-06-01 09:02:23
【问题描述】:

我的程序在 for 循环中创建了一个 numpy 数组。例如,它创建形状为(100*30*10) 的数组,然后是(160*30*10),然后可能是(120*30*10)。我必须将上述内容附加到一个空的 numpy 数组中,这样在循环结束时,它将是一个形状为 (380*30*10) 的 numpy 数组(即 100+160+120 的总和)。 numpy 数组中的第二维和第三维没有变化。

如何在 python 中执行上述操作。我尝试了以下方法。

np_model = np.append(np_model,np_temp1)
print("Appended model shape is",np_model.shape)
np_label = np.append(np_label,np_temp2)
print("Appended label shape is",np_label.shape)

np_model 是一个空数组,我将其定义为 np_model = np.empty(1,30,10),将 np_label 定义为 np_label = np.empty(1 ,str)

np_temp1 对应于每个 for 循环中的数组,例如 100*30*10120*30*10 等,np_temp2 是带有“item1”、“item2”等的字符串

np_label 是一个字符串 numpy 数组,有 1 个标签对应于np_temp1.shape[0]。但是我在 np_model 中得到的结果是扁平数组,大小为380*30*10 = 1140000

感谢任何帮助。

【问题讨论】:

  • 您正在寻找np.stack(),特别是np.vstack()
  • 那么,应该如何定义空数组呢?
  • 为什么需要一个空数组?
  • 你不应该重复使用数组追加。先列个清单。

标签: python arrays numpy append concatenation


【解决方案1】:

您可以使用 numpy concatenate 函数,将输出 numpy(s) 附加到列表中,然后将其提供给 concatenate 函数:

empty_list = []
x = np.zeros([10, 20, 4])
y = np.zeros([12, 20, 4])
empty_list.append(x)
empty_list.append(y)
z = np.concatenate(empty_list, axis=0)
print(x.shape, y.shape, z.shape)

(10, 20, 4) (12, 20, 4) (22, 20, 4)

【讨论】:

  • 但最初,我的数组是空的。如何将一个空的 numpy 数组与非空数组连接起来
  • @RamShankerG ,将它们附加到一个空列表中。检查我的代码(已编辑)。
【解决方案2】:

正如@Nullman 在评论中建议的那样(np.vstack)

你可以像这样>>> np_model = np.empty((0,30,10))创建空数组

>>> np_model = np.empty((0,30,10))

>>> a = np.random.rand(100,30,10)
>>> b = np.random.rand(160,30,10)
>>> c = np.random.rand(120,30,10)

# It can done by one-line like`np_model = np.vstack((a,b,c))`
# but i guess you have loop dependency here
>>> np_model = np.vstack((np_model,a))
>>> np_model = np.vstack((np_model,b))
>>> np_model = np.vstack((np_model,c))

>>> np_model.shape
(380, 30, 10)

【讨论】:

  • 最后做一个 vstack
【解决方案3】:

要专门回答您从空数组开始的问题,这将是我的解决方案,仅使用np.concatenate

import numpy as np

# Some arrays to append in a loop
arrays = (
    np.random.rand(100, 30, 10),
    np.random.rand(160, 30, 10),
    np.random.rand(120, 30, 10)
)

# Initial empty array
array = np.zeros((0, 30, 10))

# Appending arrays in loop
for a in arrays:
    array = np.concatenate((array, a), axis=0)

# Output shape
print(array.shape)

输出:

(380, 30, 10)

希望有帮助!

----------------------------------------
System information
----------------------------------------
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.1
NumPy:       1.18.1
----------------------------------------

【讨论】:

  • 列表追加速度更快
  • @hpaulj 我担心“收集”所有单个数组并仅使用单个 np.concatenate,因为您需要两倍于最终数组的内存(因为您将所有中间数组存储在列表),在我建议的解决方案中不会出现这种情况 - 假设要附加的数组是在上述循环中即时生成(并删除/覆盖/...)的,这就是我的理解这个问题。因此,根据实际数组的数量和大小,“收集”它们可能会导致内存问题。
  • 您的迭代不会节省内存,而是进行更多的复制。
猜你喜欢
  • 2017-12-23
  • 2015-01-29
  • 2021-12-05
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 2016-05-29
相关资源
最近更新 更多