Home > Mobile >  Writing over arrays with Numpy Python
Writing over arrays with Numpy Python

Time:09-17

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])]
  • Related