如何创建列表的numpy数组?

时间:2021-06-04 19:36:24

I want to create a numpy array in which each element must be a list, so later I can append new elements to each.

我想要创建一个numpy数组,其中每个元素必须是一个列表,因此稍后我可以向每个元素添加新元素。

I have looked on google and here on stack overflow already, yet it seems nowhere to be found.

我已经查看了谷歌和stack overflow,但是似乎找不到它。

Main issue is that numpy assumes your list must become an array, but that is not what I am looking for.

主要问题是numpy假设您的列表必须成为一个数组,但这不是我要寻找的。

2 个解决方案

#1


19  

As you discovered, np.array tries to create a 2d array when given something like

当你发现,np。数组尝试创建一个二维数组,当给定一些类似的东西

 A = np.array([[1,2],[3,4]],dtype=object)

You have apply some tricks to get around this default behavior.

您已经应用了一些技巧来绕过这种默认行为。

One is to make the sublists variable in length. It can't make a 2d array from these, so it resorts to the object array:

一个是使子列表变量的长度。它不能从这些数组中创建一个2d数组,因此它求助于对象数组:

In [43]: A=np.array([[1,2],[],[1,2,3,4]])
In [44]: A
Out[44]: array([[1, 2], [], [1, 2, 3, 4]], dtype=object)

And you can then append values to each of those lists:

然后你可以给每个列表添加值:

In [45]: for i in A: i.append(34)
In [46]: A
Out[46]: array([[1, 2, 34], [34], [1, 2, 3, 4, 34]], dtype=object)

np.empty also creates an object array:

np。空也创建一个对象数组:

In [47]: A=np.empty((3,),dtype=object)
In [48]: A
Out[48]: array([None, None, None], dtype=object)

But you then have to be careful how you change the elements to lists. np.fill is tempting, but has problems:

但是你必须注意如何将元素转换成列表。np。fill很吸引人,但也有问题:

In [49]: A.fill([])
In [50]: A
Out[50]: array([[], [], []], dtype=object)
In [51]: for i in A: i.append(34)
In [52]: A
Out[52]: array([[34, 34, 34], [34, 34, 34], [34, 34, 34]], dtype=object)

It turns out that fill puts the same list in all slots, so modifying one modifies all the others. You can get the same problem with a list of lists:

原来fill在所有的槽中都有相同的列表,所以修改一个就可以修改其他的。你可以从列表列表中得到同样的问题:

In [53]: B=[[]]*3
In [54]: B
Out[54]: [[], [], []]
In [55]: for i in B: i.append(34)
In [56]: B
Out[56]: [[34, 34, 34], [34, 34, 34], [34, 34, 34]]

The proper way to initial the empty A is with an iteration, e.g.

初始化空A的正确方法是使用迭代,例如。

In [65]: A=np.empty((3,),dtype=object)
In [66]: for i,v in enumerate(A): A[i]=[v,i]
In [67]: A
Out[67]: array([[None, 0], [None, 1], [None, 2]], dtype=object)
In [68]: for v in A: v.append(34)
In [69]: A
Out[69]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34]], dtype=object)

It's a little unclear from the question and comments whether you want to append to the lists, or append lists to the array. I've just demonstrated appending to the lists.

从问题和注释中可以看出,您是想要将列表附加到列表中,还是要将列表附加到数组中。我刚刚演示了附加到列表。

There is an np.append function, which new users often misuse. It isn't a substitute for list append. It is a front end to np.concatenate. It is not an in-place operation; it returns a new array.

有一个np。附加功能,新用户经常误用。它不是列表附加的替代品。它是np.concatenate的前端。它不是就地操作;它返回一个新的数组。

Also defining a list to add with it can be tricky:

另外,定义一个要添加的列表也很棘手:

In [72]: np.append(A,[[1,23]])
Out[72]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34], 1, 23],     dtype=object)

You need to construct another object array to concatenate to the original, e.g.

您需要构造另一个对象数组来连接到原始对象,例如。

In [76]: np.append(A,np.empty((1,),dtype=object))
Out[76]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34], None], dtype=object)

In all of this, an array of lists is harder to construct than a list of lists, and no easier, or faster, to manipulate. You have to make it a 2d array of lists to derive some benefit.

在所有这些中,一个列表数组比一个列表更难构造,操作起来也不会更容易或更快。你必须让它成为一个二维的列表数组来获得一些好处。

In [78]: A[:,None]
Out[78]: 
array([[[None, 0, 34]],
       [[None, 1, 34]],
       [[None, 2, 34]]], dtype=object)

You can reshape, transpose, etc an object array, where as creating and manipulating a list of lists of lists gets more complicated.

您可以重塑、转置等对象数组,当创建和操作列表列表时,会变得更加复杂。

In [79]: A[:,None].tolist()
Out[79]: [[[None, 0, 34]], [[None, 1, 34]], [[None, 2, 34]]]

#2


6  

If you really need a 1-d array of lists you will have to wrap your lists in your own class as numpy will always try to convert your lists to arrays inside of an array (which is more efficient but obviously requires constant size-elements), for example through

如果你真的需要一个1-d的列表数组,那么你将不得不在你自己的类中包装你的列表,因为numpy总是试图将你的列表转换成数组内部的数组(它更高效,但显然需要常量大小的元素),例如通过。

class mylist:

    def __init__(self, l):
        self.l=l

    def __repr__(self): 
        return repr(self.l)

    def append(self, x):
        self.l.append(x)

and then you can change any element without changing the dimension of others

然后你可以改变任何元素而不改变其他元素的尺寸。

>>> x = mylist([1,2,3])
>>> y = mylist([1,2,3])
>>> import numpy as np
>>> data = np.array([x,y])
>>> data
array([[1,2,3], [1,2,3]], dtype=object)
>>> data[0].append(2)
>>> data
array([[1,2,3,2], [1,2,3]], dtype=object)

Update

As suggested by ali_m there is actually a way to force numpy to simply create a 1-d array for references and then feed them with actual lists

正如ali_m所建议的,实际上有一种方法可以强制numpy为引用创建一个一维数组,然后用实际的列表提供它们

>>> data = np.empty(2, dtype=np.object)
>>> data[:] = [1, 2, 3], [1, 2, 3]
>>> data
array([[1, 2, 3], [1, 2, 3]], dtype=object)
>>> data[0].append(4)
>>> data
array([[1, 2, 3, 4], [1, 2, 3]], dtype=object)

#1


19  

As you discovered, np.array tries to create a 2d array when given something like

当你发现,np。数组尝试创建一个二维数组,当给定一些类似的东西

 A = np.array([[1,2],[3,4]],dtype=object)

You have apply some tricks to get around this default behavior.

您已经应用了一些技巧来绕过这种默认行为。

One is to make the sublists variable in length. It can't make a 2d array from these, so it resorts to the object array:

一个是使子列表变量的长度。它不能从这些数组中创建一个2d数组,因此它求助于对象数组:

In [43]: A=np.array([[1,2],[],[1,2,3,4]])
In [44]: A
Out[44]: array([[1, 2], [], [1, 2, 3, 4]], dtype=object)

And you can then append values to each of those lists:

然后你可以给每个列表添加值:

In [45]: for i in A: i.append(34)
In [46]: A
Out[46]: array([[1, 2, 34], [34], [1, 2, 3, 4, 34]], dtype=object)

np.empty also creates an object array:

np。空也创建一个对象数组:

In [47]: A=np.empty((3,),dtype=object)
In [48]: A
Out[48]: array([None, None, None], dtype=object)

But you then have to be careful how you change the elements to lists. np.fill is tempting, but has problems:

但是你必须注意如何将元素转换成列表。np。fill很吸引人,但也有问题:

In [49]: A.fill([])
In [50]: A
Out[50]: array([[], [], []], dtype=object)
In [51]: for i in A: i.append(34)
In [52]: A
Out[52]: array([[34, 34, 34], [34, 34, 34], [34, 34, 34]], dtype=object)

It turns out that fill puts the same list in all slots, so modifying one modifies all the others. You can get the same problem with a list of lists:

原来fill在所有的槽中都有相同的列表,所以修改一个就可以修改其他的。你可以从列表列表中得到同样的问题:

In [53]: B=[[]]*3
In [54]: B
Out[54]: [[], [], []]
In [55]: for i in B: i.append(34)
In [56]: B
Out[56]: [[34, 34, 34], [34, 34, 34], [34, 34, 34]]

The proper way to initial the empty A is with an iteration, e.g.

初始化空A的正确方法是使用迭代,例如。

In [65]: A=np.empty((3,),dtype=object)
In [66]: for i,v in enumerate(A): A[i]=[v,i]
In [67]: A
Out[67]: array([[None, 0], [None, 1], [None, 2]], dtype=object)
In [68]: for v in A: v.append(34)
In [69]: A
Out[69]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34]], dtype=object)

It's a little unclear from the question and comments whether you want to append to the lists, or append lists to the array. I've just demonstrated appending to the lists.

从问题和注释中可以看出,您是想要将列表附加到列表中,还是要将列表附加到数组中。我刚刚演示了附加到列表。

There is an np.append function, which new users often misuse. It isn't a substitute for list append. It is a front end to np.concatenate. It is not an in-place operation; it returns a new array.

有一个np。附加功能,新用户经常误用。它不是列表附加的替代品。它是np.concatenate的前端。它不是就地操作;它返回一个新的数组。

Also defining a list to add with it can be tricky:

另外,定义一个要添加的列表也很棘手:

In [72]: np.append(A,[[1,23]])
Out[72]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34], 1, 23],     dtype=object)

You need to construct another object array to concatenate to the original, e.g.

您需要构造另一个对象数组来连接到原始对象,例如。

In [76]: np.append(A,np.empty((1,),dtype=object))
Out[76]: array([[None, 0, 34], [None, 1, 34], [None, 2, 34], None], dtype=object)

In all of this, an array of lists is harder to construct than a list of lists, and no easier, or faster, to manipulate. You have to make it a 2d array of lists to derive some benefit.

在所有这些中,一个列表数组比一个列表更难构造,操作起来也不会更容易或更快。你必须让它成为一个二维的列表数组来获得一些好处。

In [78]: A[:,None]
Out[78]: 
array([[[None, 0, 34]],
       [[None, 1, 34]],
       [[None, 2, 34]]], dtype=object)

You can reshape, transpose, etc an object array, where as creating and manipulating a list of lists of lists gets more complicated.

您可以重塑、转置等对象数组,当创建和操作列表列表时,会变得更加复杂。

In [79]: A[:,None].tolist()
Out[79]: [[[None, 0, 34]], [[None, 1, 34]], [[None, 2, 34]]]

#2


6  

If you really need a 1-d array of lists you will have to wrap your lists in your own class as numpy will always try to convert your lists to arrays inside of an array (which is more efficient but obviously requires constant size-elements), for example through

如果你真的需要一个1-d的列表数组,那么你将不得不在你自己的类中包装你的列表,因为numpy总是试图将你的列表转换成数组内部的数组(它更高效,但显然需要常量大小的元素),例如通过。

class mylist:

    def __init__(self, l):
        self.l=l

    def __repr__(self): 
        return repr(self.l)

    def append(self, x):
        self.l.append(x)

and then you can change any element without changing the dimension of others

然后你可以改变任何元素而不改变其他元素的尺寸。

>>> x = mylist([1,2,3])
>>> y = mylist([1,2,3])
>>> import numpy as np
>>> data = np.array([x,y])
>>> data
array([[1,2,3], [1,2,3]], dtype=object)
>>> data[0].append(2)
>>> data
array([[1,2,3,2], [1,2,3]], dtype=object)

Update

As suggested by ali_m there is actually a way to force numpy to simply create a 1-d array for references and then feed them with actual lists

正如ali_m所建议的,实际上有一种方法可以强制numpy为引用创建一个一维数组,然后用实际的列表提供它们

>>> data = np.empty(2, dtype=np.object)
>>> data[:] = [1, 2, 3], [1, 2, 3]
>>> data
array([[1, 2, 3], [1, 2, 3]], dtype=object)
>>> data[0].append(4)
>>> data
array([[1, 2, 3, 4], [1, 2, 3]], dtype=object)