0

I have a Numpy array, "nFuncs" containing function objects as blow:

array([ [<bound method ncNN.sigmoid of <__main__.ncNN object at 0x11c01f510>>, 
         <bound method ncNN.sigmoid of <__main__.ncNN object at 0x11c01f510>>, 
         <bound method ncNN.sigmoid of <__main__.ncNN object at 0x11c01f510>>],
        [<bound method ncNN.sigmoid of <__main__.ncNN object at 0x11c01f510>>,
         <bound method ncNN.sigmoid of <__main__.ncNN object at 0x11c01f510>>]], dtype=object)

What's the legitimate way to index this array? when I tried nFuncs[1,1], I have IndexError: too many indices for array. However, nFuncs[1][1] works. Can you explain why I cannot use nFuncs[1,1]?

6
  • 2
    It could be stored as list of list. Have you tried type(nFuncs[1])? Commented Nov 7, 2016 at 21:33
  • What's the shape? Commented Nov 7, 2016 at 21:35
  • @hpaulj it is (2,) Commented Nov 7, 2016 at 23:15
  • @DeanLa yes, it is a list. Commented Nov 7, 2016 at 23:16
  • So it is 1d, and can only be indexed with [1]. Commented Nov 7, 2016 at 23:24

2 Answers 2

1

Make a nested list:

In [8]: alist=[[1,2,3],[4,5]]
In [9]: len(alist)
Out[9]: 2

It's a list of 2 items; the items happen to be lists. In some sort meta view it is 2d, but nothing about the list itself is 2d.

Make an array from it:

In [10]: arr = np.array(alist)
In [11]: arr.shape
Out[11]: (2,)
In [12]: arr.dtype
Out[12]: dtype('O')
In [13]: arr
Out[13]: array([[1, 2, 3], [4, 5]], dtype=object)
In [14]: arr[0]
Out[14]: [1, 2, 3]
In [15]: type(arr[0])
Out[15]: list

It too has 2 elements, in fact the same 2 sublists as alist (same id)

In [16]: id(alist[0])
Out[16]: 2992863468
In [17]: id(arr[0])
Out[17]: 2992863468

If I change an element of one of those sublists, the change appears in the other structure

In [18]: arr[0][1]=3
In [19]: arr
Out[19]: array([[1, 3, 3], [4, 5]], dtype=object)
In [20]: alist
Out[20]: [[1, 3, 3], [4, 5]]

For most purposes an object array like this is just like a list. You can reshape it, eg. `arr.reshape(2,1)', but you can't append to it. And to perform most actions you (or numpy) has to iterate through the elements just as if it were a list.

Contrast that with a 2d array of integers

In [21]: A=np.array([[1,2,3],[4,5,6]])
In [22]: A
Out[22]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [23]: A.shape
Out[23]: (2, 3)
In [24]: A.dtype
Out[24]: dtype('int32')

May be it will to visualize the object barrier if I change the elements of arr into arrays:

In [26]: arr[0]=np.array(arr[0])
In [27]: arr[1]=np.array(arr[1])
In [28]: arr
Out[28]: array([array([1, 3, 3]), array([4, 5])], dtype=object)

It is now an array of arrays; but that still not the same as a 2d array.

Sign up to request clarification or add additional context in comments.

3 Comments

I really appreciate your kind explanation. Now I think I started to understand the difference between object array and some other types(?) of array. A few more questions. When does an array is initiated as an object array and fixed type array? For example, A = np.array([['1','1'],['sd','a']]) makes "'|S2'" type(?) 2D array, not an object array. Then, can I think that, if I create an array with sub elements with the same lengths, it will always make a fixed type multi-dimensional array? Also, can you please explain the rationale behind A[x,x] indexing in higher dimension arrays?
np.array tries to create as high a dimension array as it can - working all the way down through equal length nested arrays. Limiting that depth requires some trickery. It's been the subject of a number of SO questions.
Thanks very much. I will look into more documentations
1

The array has shape (2,): It is 1-dimensional. This is because the first and the second sub-lists in the constructor have different lengths. So this is interpreted as a 1-d array of 2 lists. To get an array of functions insert a function into the second list (or remove one from the first).

4 Comments

Thanks for your input. Then, if I just want to use the array as above, is it the only way to index like name[I][j]?
In any case you have to first index into the array and then into the resulting list. There are in principle more complicated ways to index into the array, but I think that will not make sense or help in your case.
Then, Numpy arrays like a = np.array([[1,2,3],[4,5,6]]) are an exception, given that I can access an element using a[1, 2]?
More the rule than the exception :) To access an element like that you need a 2D array, which can't be constructed from 2 lists of differing lengths, so numpy doesn't and gives you an array of lists instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.