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]
CodePudding user response:
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]
CodePudding user response:
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])]