Py-ser
Py-ser

Reputation: 2098

Replace zeroes in array with different values for different halves of the array

I have an array of floats whose size is not known in advance. There are zero values in it and other floats. I want to replace its zeroes with a certain value only for part of the array, let's say for the first third of the array, with another value for the second third, and another value for the last third.

I was trying to use my_array[:my_array.size//3:] = first_value as suggested here as part of a list comprehension:

my_array = np.asarray([first_value for x in my_array[:my_array.size//3:] if x == 0])

but this reduces the array to only its first third. How can I replace the zeroes in the way described above?

Upvotes: 1

Views: 69

Answers (2)

Okapi575
Okapi575

Reputation: 718

Lets try with a loop for a array length that can not always be devided by the number of parts

import numpy as np

number_of_parts=3
length_of_parts=int(np.ceil(my_array.size/number_of_parts))
Values=[1,2,3]

Parts=[[counter*length_of_parts,min((counter+1)*length_of_parts,my_array.size)]for counter in range(number_of_parts)]

for (start,end),Value in zip(Parts,Values):
     my_array[start,end][my_array[start,end]==0]=Value

Upvotes: 0

Ehsan
Ehsan

Reputation: 12397

You can use mask to get the desired indices first and then assign them any value at once without loop:

mask = np.where(my_array==0)[0]
my_array[mask[mask<my_array.size//3]] = first_value
my_array[mask[np.logical_and(mask>=my_array.size//3, mask<2*my_array.size//3)]] = second_value
my_array[mask[mask>=2*my_array.size//3]] = third_value

If you would like to chunk your array into more pieces, I would recommend looping this code.

Note that this will NOT work as it creates a copy of array and changes that:

#THIS DOES NOT WORK, it changes values of a copy of my_array and not the original array itself
my_array[my_array==0][:my_array.size//3] = first_value

Upvotes: 1

Related Questions