Вы можете использовать маску, чтобы сначала получить нужные индексы, а затем присвоить им любое значение сразу без l oop:
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
Если вы хотите разделить массив на несколько частей, я бы рекомендуем зацикливать этот код.
Обратите внимание, что это НЕ будет работать, поскольку оно создает копию массива и изменяет это:
#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