sempraEdic
sempraEdic

Reputation: 138

How to count the amount of elements in a particular abstract n-dimensional NumPy array?

I am intended to count how many integers are stored in a particular abstract n-dimensional array (I am not sure onthe proper term for this). For instance, here's the output of the numpy array named 'result':

In [1]: print(f"{result} \n {type(result)}")
Out [1]: [list([[[[2, 5], [6, 8]]], [[[[5, 7], [8, 9]]], [[[7, 8], [9, 9]]]]]) list([[[8, 9], [9, 2]]])] 
<class 'numpy.ndarray'>

Then, how to count the number of elements on that "result". The expected outcome is 16 since there are 16 integers (2, 5, 6, 8, ..., 8, 9, 9, 2) stored on the "result" variable?

Upvotes: 0

Views: 486

Answers (2)

hpaulj
hpaulj

Reputation: 231335

You have a 2 element object dtype array, that contains lists:

In [68]: result = np.array([list([[[[2, 5], [6, 8]]], [[[[5, 7], [8, 9]]], [[[7, 8], [9, 9]]]]]), list([[[8, 9
    ...: ], [9, 2]]])], object)
In [71]: print(result)
[list([[[[2, 5], [6, 8]]], [[[[5, 7], [8, 9]]], [[[7, 8], [9, 9]]]]])
 list([[[8, 9], [9, 2]]])]
In [72]: result.shape
Out[72]: (2,)

The 2nd list can be made into a (2,2) array, with 4 elements:

In [73]: np.array(result[1])
Out[73]: 
array([[[8, 9],
        [9, 2]]])
In [74]: np.array(result[1]).size
Out[74]: 4

But the lists in the first element are more deeply nested:

In [75]: np.array(result[0], object)
Out[75]: 
array([list([[[2, 5], [6, 8]]]),
       list([[[[5, 7], [8, 9]]], [[[7, 8], [9, 9]]]])], dtype=object)
In [76]: np.array(np.array(result[0], object)[0])
Out[76]: 
array([[[2, 5],
        [6, 8]]])
In [77]: np.array(np.array(result[0], object)[1])
Out[77]: 
array([[[[5, 7],
         [8, 9]]],


       [[[7, 8],
         [9, 9]]]])
In [78]: _.shape
Out[78]: (2, 1, 2, 2)

One is (2,1,2) shape, the other (2,1,2,2). That's 4 and 8 element, so 16 in total.

We could write a recursive function that works its way through the elements, deciding whether it's reached the "bottom" or whether it needs to go down another layer.

There is also a way of "flattening" lists (itertools.chain?), but even with that we need to use it recursively.


In [80]: import itertools
In [81]: list(itertools.chain(*result))
Out[81]: 
[[[[2, 5], [6, 8]]],
 [[[[5, 7], [8, 9]]], [[[7, 8], [9, 9]]]],
 [[8, 9], [9, 2]]]
In [82]: len(_)
Out[82]: 3
In [83]: [list(itertools.chain(*x)) for x in Out[81]]
Out[83]: [[[2, 5], [6, 8]], [[[5, 7], [8, 9]], [[7, 8], [9, 9]]], [8, 9, 9, 2]]
In [84]: len(_)
Out[84]: 3
In [85]: list(itertools.chain(*Out[83]))
Out[85]: [[2, 5], [6, 8], [[5, 7], [8, 9]], [[7, 8], [9, 9]], 8, 9, 9, 2]

edit

Recent how to remove brackets from these individual elements?

got a duplicate link How to make a flat list out of a list of lists?

That has a number of functions (mostly recursive) that flatten a list of arbitrary depth. Taking the first

In [100]: def flatten(itr):
     ...:     for x in itr:
     ...:         try:
     ...:             yield from flatten(x)
     ...:         except TypeError:
     ...:             yield x
In [101]: list(flatten(result))
Out[101]: [2, 5, 6, 8, 5, 7, 8, 9, 7, 8, 9, 9, 8, 9, 9, 2]
In [102]: len(_)
Out[102]: 16

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249103

result.size will tell you how many elements are in a NumPy array (see numpy.ndarray.size). The problem is that your array is not simply an array, but for some reason it is an array of lists of lists of lists....

The first thing you need to do is clean your data so there are not these list types inside your array. Then result.size will do what you want.

Upvotes: 2

Related Questions