Python 如何创建一个 numpy 列表数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33983053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a numpy array of lists?
提问by Ricardo Silveira
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.
我已经在谷歌和这里查看了堆栈溢出,但似乎无处可寻。
Main issue is that numpy assumes your list must become an array, but that is not what I am looking for.
主要问题是 numpy 假设您的列表必须成为一个数组,但这不是我要找的。
采纳答案by hpaulj
As you discovered, np.array
tries to create a 2d array when given something like
正如你所发现的,np.array
当给出类似的东西时尝试创建一个二维数组
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:
一种是使子列表的长度可变。它不能从这些创建一个二维数组,所以它求助于对象数组:
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.empty
还创建了一个对象数组:
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.
初始化的正确方法empty
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.append
新用户经常误用的功能。它不能替代列表附加。它是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]]]
===
===
As shown in https://stackoverflow.com/a/57364472/901925, np.frompyfunc
is a good tool for creating an array of objects.
如https://stackoverflow.com/a/57364472/901925所示,np.frompyfunc
是创建对象数组的好工具。
np.frompyfunc(list, 0, 1)(np.empty((3,2), dtype=object))
回答by lejlot
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
如果您确实需要一个一维列表数组,则必须将列表包装在您自己的类中,因为 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)
回答by Dmitriy
data = np.empty(20, dtype=np.object)
for i in range(data.shape[0]):
data[i] = []
data[i].append(i)
print(data)
The result will be:
结果将是:
[list([0]) list([1]) list([2]) list([3]) list([4]) list([5]) list([6]) list([7]) list([8]) list([9]) list([10]) list([11]) list([12]) list([13]) list([14]) list([15]) list([16]) list([17]) list([18]) list([19])]
回答by Nadav
A simple way would be:
一个简单的方法是:
A = [[1,2],[3,4]]
B = np.array(A+[[]])[:-1]