0

Consider the variable "A" and an array with several nested arrays. Both "A" and the nested arrays contain the same amount of elements, in this case 5. Each nested array are also nested together in groups of 3.

A=[10,20,30,40,50]
array=[[[1,5,8,3,4],[18,4,-8,4,21],[-8,12,42,16,-9]], ...]

I was wondering how I can replace the elements in each nested array with the corresponding elements in A if the value of the element in the nested array exceeds a certain threshold. Otherwise, if the element fails to exceed the threshold, replace with zero.

For example, if the threshold is 10 in this example, the result would be:

array=[[[0,0,0,0,0],[10,0,0,0,50],[0,20,30,40,0]], ...]

I know this might be a simple problem, but I'm having trouble comprehending multidimensional arrays, especially if they are greater than 2-dimensions. The bigger question is, how would I do this if those arrays are nested under many arrays without using several for loops? My incorrect attempt:

for a in array:
   for x in a:
      for i in x:
         if a[i]>10:
            a[i]=A[i]
         else:
            a[i]=0
0

2 Answers 2

2

Your attempt is not working because first of all you are using the list value i as an index. In the line for i in x: the variable i will take each value of the list x, and if you need the index of it as well, you can use for id, i in enumerate(x) which gives you each value of the list as i and its index as id.

Moreover, to update the array, it is not enough to update x inside the loop, you need to update the array directly. And of course you can use list comprehension for simplicity in the last loop. So a solution to your problem could look like this:

for i1, val1 in enumerate(array):
    for i2, val2 in enumerate(val1):
        array[i1][i2] = [y if x>10 else 0 for (x, y) in zip(val2, A)]

As for your bigger question, the general solution when you have multiple nested lists and you don't want to use for loops is to implement recursive functions.

Here, one recursive solution to your problem would be:

def my_recursive_fun(input):
    if isinstance(input, list) and isinstance(input[0], list):
        return [my_recursive_fun(item) for item in input]
    else:
        return [y if x>10 else 0 for (x, y) in zip(input, [10,20,30,40,50])]

array=[[[1,5,8,3,4],[18,4,-8,4,21],[-8,12,42,16,-9]]]
new_array = my_recursive_fun(array)

The good thing about recursive solution is that it works with any number of nested lists (of course there are limits) without changing the code.

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

2 Comments

Hello Ali, thank you very much for your answer! Although this works for typical lists, if we use array2=np.asarray(array), the function my_recursive_fun(array2) leads to the following error: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). I've tried x.any()>10 and (x>10).any() to no avail. Do you happen to know how numpy arrays affect this?
If you change your input data type from Python List to NumPy ndarray, the check in the if statement needs to be updated as well and you have to check if the input is a list of numbers like this: if isinstance(input[0], np.ndarray).
1

If the nesting of your array is arbitrary deep, then go for a recursive function:

def apply_threshold(substitutes, limit, source):
    if isinstance(source[0], list):  # recursive case
        return [apply_threshold(substitutes, limit, elem) for elem in source]
    else:  # base case
        return [subst if value >= limit else 0 
                for subst, value in zip(substitutes, source)]

Here is how to use it:

A = [10,20,30,40,50]
array = [[[1,5,8,3,4],[18,4,-8,4,21],[-8,12,42,16,-9]]]
result = apply_threshold(A, 10, array)
print(result)  # [[[0, 0, 0, 0, 0], [10, 0, 0, 0, 50], [0, 20, 30, 40, 0]]]

Comments

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.