2

How can I write a code where it formats the [a,b,c] values permanently within the for loop and turns the negative values into zeroes. The map lambda function formater works as expected but I write over the arrays within the for loop. The code below does not work how can I get the expected output?

import numpy as np 

a = np.array([2323,34,12,-23,12,4,-33,-2,-1,11,-2])
b = np.array([12,-23-1,-1,-3,-12])
c = np.array([23,45,3,13,-1992,5])

format_number = lambda n: n if n % 1 else int(n)
for count,formater in enumerate([a, b, c]):
    formater = list(map(lambda n: 0 if n < 0 else format_number(n), formater))
    formater[count]= formater

Output:

[2323   34   12  -23   12    4  -33   -2   -1   11   -2]
[ 12 -24  -1  -3 -12]
[   23    45     3    13 -1992     5]

Expected output:

[2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0]
[12, 0, 0, 0, 0]
[23, 45, 3, 13, 0, 5]
2
  • Does this answer your question? Replace negative values in an numpy array Commented Sep 14, 2021 at 6:29
  • print(formater)? instead of formater[count]= formater Commented Sep 14, 2021 at 6:31

2 Answers 2

1

It's better with np.vectorize:

format_number = lambda n: n if n % 1 else int(n)
for count, formater in enumerate([a, b, c]):
    formater[formater < 0] = 0
    formatter = np.vectorize(format_number)(formater)
    print(formater.tolist())

To fix your code do:

format_number = lambda n: n if n % 1 else int(n)
for count,formater in enumerate([a, b, c]):
    formater = list(map(lambda n: 0 if n < 0 else format_number(n), formater))
    print(formater)

Both Output:

[2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0]
[12, 0, 0, 0, 0]
[23, 45, 3, 13, 0, 5]
Sign up to request clarification or add additional context in comments.

1 Comment

Why is vectorize better than the list map? I thought the OP want to change the original arrays, not just print new ones. Or did I read the question wrong?
0

What you are trying to do should work with a list as well as array.

In [163]: a = [2323,34,12,-23,12,4,-33,-2,-1,11,-2]
     ...: b = [12,-23-1,-1,-3,-12]
     ...: c = np.array([23,45,3,13,-1992,5])

Collect the variables in a list:

In [164]: alist = [a,b,c]
In [165]: alist
Out[165]: 
[[2323, 34, 12, -23, 12, 4, -33, -2, -1, 11, -2],
 [12, -24, -1, -3, -12],
 array([   23,    45,     3,    13, -1992,     5])]

If I iterate like you do, and assign a new object to item, nothing changes in alist.

In [166]: for item in alist:
     ...:     item = [1,2,3]
     ...: 
In [167]: alist
Out[167]: 
[[2323, 34, 12, -23, 12, 4, -33, -2, -1, 11, -2],
 [12, -24, -1, -3, -12],
 array([   23,    45,     3,    13, -1992,     5])]

This is critical; when iterating through a list, you can't replace the iteration variable; otherwise you loose connection to the source.

Instead we modify the item, change it in-place.

In [168]: for item in alist:
     ...:     for i,v in enumerate(item):
     ...:         if v<0:
     ...:             item[i] = 0
     ...: 
     ...: 

now the change appears in the list:

In [169]: alist
Out[169]: 
[[2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0],
 [12, 0, 0, 0, 0],
 array([23, 45,  3, 13,  0,  5])]

Verify that this has changed the original list/arrays:

In [170]: a
Out[170]: [2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0]

Let's try something closer to your code:

In [171]: format_number = lambda n: n if n % 1 else int(n)
In [174]: formater = [2323,34,12,-23,12,4,-33,-2,-1,11,-2]
In [175]: new = list(map(lambda n: 0 if n < 0 else format_number(n), formater))
In [176]: new
Out[176]: [2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0]

With the list(map()) I've created a new list. If want use this in a loop, as I did with item, I have to modify the original, e.g.

In [177]: formater[:] = new
In [178]: formater
Out[178]: [2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0]

Applying this to the original variables:

In [179]: a = [2323,34,12,-23,12,4,-33,-2,-1,11,-2]
     ...: b = [12,-23-1,-1,-3,-12]
     ...: c = np.array([23,45,3,13,-1992,5])
In [180]: alist = [a,b,c]
In [181]: for item in alist:
     ...:     item[:]=list(map(lambda n: 0 if n < 0 else format_number(n), item))
     ...: 
In [182]: alist
Out[182]: 
[[2323, 34, 12, 0, 12, 4, 0, 0, 0, 11, 0],
 [12, 0, 0, 0, 0],
 array([23, 45,  3, 13,  0,  5])]

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.