How do I make a grid of empty lists in numpy that "accepts" append?
I am trying to use numpy.append but something went wrong and it just doesn't do it anymore for me. Can someone explain why I am getting the error?
>>> np.array([[], [], []]).shape
(3, 0)
>>> a=[[], [], []]
>>> a[1].append(3)
>>> a
[[], [3], []]
>>> b=np.array(a)
>>> b[0].append(3)
array([[3], [3], []], dtype=object)
This all makes sense to me, but when I try the following it stops working.
>>> c=np.array((3,0),dtype=object)
>>> c[0].append(3)
AttributeError: 'int' object has no attribute 'append'
????
>>> np.empty((3,1))[0].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'
>>> np.empty((3,0))[1].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'
>>>np.empty((6,1),dtype=object)[0].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'
source to share
Don't look at the form; check dtype, and if object, nature of elements
In [282]: np.array([[], [], []])
Out[282]: array([], shape=(3, 0), dtype=float64)
A 2d array of floats. np.array
tries to create a multidimensional array of numbers; it only makes an array of objects when it cannot do it.
In [283]: b=np.array([[],[3],[]])
In [284]: b
Out[284]: array([[], [3], []], dtype=object)
Here the 3 sublists are of different size, so it cannot create a 2d array; the result is an array of objects, where the objects are lists and have an add method.
In [286]: c=np.array((3,0), object)
In [287]: c
Out[287]: array([3, 0], dtype=object)
This is an array of objects (2,); 2 elements are numbers. The numbers do not have an add method.
In [288]: np.empty((3,1))
Out[288]:
array([[ 0.],
[ 0.],
[ 0.]])
A (3,1) array of floats. There is no method for adding numbers or arrays.
In [289]: np.empty((3,0))
Out[289]: array([], shape=(3, 0), dtype=float64)
Another 2d array of floats
In [290]: np.empty((6,1),object)
Out[290]:
array([[None],
[None],
[None],
[None],
[None],
[None]], dtype=object)
2d array of dtype object. In this case, they are initialized to None
. Again there is no add method.
More on creating an array of lists
array sizes of arrays in numpy
and
How to keep numpy from translation when creating an array of objects from different array shapes
In [305]: d=np.empty((3,),object)
In [306]: d
Out[306]: array([None, None, None], dtype=object)
In [307]: d.fill([])
In [308]: d
Out[308]: array([[], [], []], dtype=object) # array of lists
In [309]: d[0].append([1,2,3])
In [310]: d
Out[310]: array([[[1, 2, 3]], [[1, 2, 3]], [[1, 2, 3]]], dtype=object)
But oops - these lists are the same object (pointer) :( I need to put a different list on each element. Now I can add to them individually.
In [311]: d[...]=[[],[1,2,3],[2]]
In [312]: d
Out[312]: array([[], [1, 2, 3], [2]], dtype=object)
In [313]: d[0].append([2,3])
In [314]: d
Out[314]: array([[[2, 3]], [1, 2, 3], [2]], dtype=object)
I think you need to bite the bullet and use a list to initialize an array of objects from lists. There is not a short stretch:
In [319]: d=np.empty((3,),object)
In [320]: d[...]=[[] for _ in range(3)]
In [321]: d
Out[321]: array([[], [], []], dtype=object)
In [323]: d
Out[323]: array([[], [3], []], dtype=object)
source to share
First of all, stop updating your question when someone answers it correctly. Accept / support the answer and ask a new question when ready. SO is a Q&A site designed to help future visitors view your question, not just you. The invalidity of all good answers by changing the context entirely for your own benefit defeats the purpose of this site, to say the least.
Second, np.array([[], [3], []])
ends up dtype=object
because it is a dangling array. [[], [], []]
and [[3], [3], [3]]
having uniform length in all elements over all dimensions will create numeric arrays.
np.zeros((6,),dtype=object)
creates an empty array of object references (containing NULL). When you fill it []
, you fill it with a reference to the same python list
in every element. numpy
doesn't know which object you are transitioning to ndarray.fill
, so it doesn't call the type constructor list
on every element as you seem to expect. It just copies the link you shared six times. After that it should be clear why changing the contents of this list makes it visible that all the elements of the array have changed.
source to share