1

I have the following three numpy arrays:

a = np.array([ 1, 2, 3, 4, 2, 3, 4 ])
b = np.array([ [1], [2,3,4], [], [2,3,4] ])
c = np.array([ 1, [2,[3,4]], [], [2,3,4] ])

How can I use a single function f that would work on all three arrays, returning the values in all sublists, in unaltered order and unaltered type?

So the answer should be f(a) == f(b) == f(c) == a.

I found the following trick here (Concatenation of inner lists or ints):

def f(b):
    np.array([a for x in np_array for a in (x if isinstance(x, list) else [x])])

But this does not work for array c.

Community
  • 1
  • 1
physicalattraction
  • 6,485
  • 10
  • 63
  • 122

3 Answers3

2

For those who don't need to handle nesting, ndarray.flatten does the trick.

For your use case, I'm not aware of a numpy solution, but here is a pure python alternative:

>>> b = np.array([ [1], [2,3,4], [], [2,3,4] ])
>>> from compiler.ast import flatten
>>> np.array(flatten(b))
array([1, 2, 3, 4, 2, 3, 4])

It will only work on python 2.

For python 3 try this:

from collections import Iterable

def flatten(collection):
  for element in collection:
    if isinstance(element, Iterable) and not isinstance(element, str):
      for x in flatten(element):
        yield x
    else:
      yield element

def flatten_array(array):
    return np.array(flatten(array))
wim
  • 338,267
  • 99
  • 616
  • 750
  • Thanks for the solution with generators. However, it does not seem to work. It does never eneter the for element in collection loop (I placed a print statement in there, which I don't see back). Should I somehow call the flatten generator inan iterative way? How is this done? – physicalattraction Jul 09 '14 at 05:56
1

In Python3 there is an inbuild function flatten() for that

import numpy as np
arr=np.array([[4,7,-6],[3,0,8],[2,0,-4]])
print(arr)
print(arr.flatten())
0

ravel() method is more efficient than all

import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a.ravel())# flattened array
Prajot Kuvalekar
  • 5,128
  • 3
  • 21
  • 32