如何将基元列表附加到对象的numpy数组

时间:2018-07-06 13:10:57

标签: python numpy

编辑:关于如何如何做到这一点以及如何找到替代品,我已经收到了很多有用的反馈,但是使之有用取决于我用例的特质,这将使这个问题更少对他人有用。目前,我正在寻找使用这种结构的数据的替代方法。我正在寻找为什么在numpy中似乎不可能做到这一点(或者在并非不可能的情况下如何做到这一点)

我有一个numpy数组,看起来像

a = array([list([1]), list([4, 5])], dtype=object)

我想附加一个列表,

b = [2, 3, 4]

要获得类似的结果

array([list([1]), list([4, 5]), list([2, 3, 4])], dtype=object)

但是,我尝试过的每种方法都会产生:

array([list([1]), list([4, 5]), 2, 3, 4], dtype=object)

我已经尝试了vstack,连接和追加,以及将它们包装在列表或ndarrays中。

我为什么要这样做?基本上,我在ndarray中有很多数据,这些数据将被送入sklearn。我想要一个3d ndarray(数据集x数据点x特征),但是传入的数据不好,某些东西的长度不同,因此最里面的维必须是列表。我正在尝试附加一个派生功能,但该功能不断失败。我设法对操作进行了重新排序,以避免需要执行此附加操作,但是我仍然想知道如何执行此操作。对于numpy来说,这似乎是一个奇怪的失败。 编辑:简而言之,外部数组必须是ndarray ,因为它实际上是二维数组,并且经常使用复杂的切片,而追加操作很少发生。

2 个答案:

答案 0 :(得分:0)

首先附加到数组是昂贵且通常有臭味的操作。问题是数组的内容可能是可变的,但底层缓冲区的地址不是可变的。每次添加元素时,整个内容都会重新分配并复制。据我所知,甚至没有像list那样进行摊销的尝试。

如果您希望使用稍微不同的方法,则建议像现在一样将数据保存在list中。只要您实际需要数组,就可以将列表转换为数组。请记住,这比每次重新分配给新数组都便宜,并且与附加数相比,您可能不必经常这样做:

stack = [[1], [4, 5]]
a = np.array(stack, dtype=np.object)
# do stuff to the array

...

stack.append([2, 3, 4])
a = np.array(stack, dtype=np.object)

现在就可以理解您的问题了

如果您的目标只是弄清楚如何将元素添加到对象数组而又不妨碍它成为列表,则必须首先创建一个空的数组或元素。我建议不要创建空元素并将其明确设置为列表,而不是像某些注释所建议的那样用假元素来强制类型。如果您想要一个干净的界面,可以将该操作包装在一个函数中。

这里是一个例子:

b = [2, 3, 4]
c = np.empty(1, dtype=np.object)
c[0] = b
a = np.concatenate((a, c))

OR

a = np.append(a, c)

当然,这不如np.array([b], dtype=np.object)干净,但这只是numpy处理数组的一种人工产物。之所以必须这样做,是因为numpy将列表或元组中的任何内容都视为特殊项目,您希望将其转换为外层数组。

答案 1 :(得分:-1)

如果您确实必须将np.ndarraydtype=object一起使用,则可以执行以下操作:

a = np.array([list([1]), list([4, 5])], dtype=object)
b = [2, 3, 4]
a = np.hstack((a, np.empty(1)))
a[-1] = b

(或者,在完全导入numpy的情况下,当然请删除np.。)
但我建议不要使用np.ndarray中的dtype=object。而是将list与以下项一起使用:

a = [[list([1]), list([4, 5])]]
b = [2, 3, 4]
a.append(b)

现在,如果您真的想将a作为np.ndarray,则可以执行以下操作:

a = np.array(a)