Wintro Wintro - 1 month ago 9
Python Question

Converting a 3D List to a 3D NumPy array

Currently, I have a 3D Python list in jagged array format.

A = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0], [0], [0]]]


Is there any way I could convert this list to a NumPy array, in order to use certain NumPy array operators such as adding a number to each element.

A + 4
would give
[[[4, 4, 4], [4, 4, 4], [4, 4, 4]], [[4], [4], [4]]]
.

Assigning
B = numpy.array(A)
then attempting to
B + 4
throws a type error.

TypeError: can only concatenate list (not "float") to list


Is a conversion from a jagged Python list to a NumPy array possible while retaining the structure (I will need to convert it back later) or is looping through the array and adding the required the better solution in this case?

Answer

The answers by @SonderingNarcissit and @MadPhysicist are already quite nice.

Here is a quick way of adding a number to each element in your list and keeping the structure. You can replace the function return_number by anything you like, if you want to not only add a number but do something else with it:

def return_number(my_number):
    return my_number + 4


def add_number(my_list):

    if isinstance(my_list, (int, float)):
        return return_number(my_list)
    else:
        return [add_number(xi) for xi in my_list]

A = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0], [0], [0]]]

Then

print add_number(A)

gives you the desired output:

[[[4, 4, 4], [4, 4, 4], [4, 4, 4]], [[4], [4], [4]]]

So what it does is that it look recursively through your list of list and everytime it finds a number it adds the value 4; this should work for arbitrarily deep nested lists. That currently only works for numbers and lists; if you also have e.g. also dictionaries in your lists then you would have to add another if-clause.

Comments