Substitude np.ones()*0 by np.zeros()

The following code seems quite difficult to read and rather confusing to me:

y_laser1 = np.ones(nr_of_points, dtype='uint8')*0
y_laser2 = np.ones(nr_of_points, dtype='uint8')*1
y_laser3 = np.ones(nr_of_points, dtype='uint8')*0 # 2
y_laser_dead_zone = np.ones(5*nr_of_points, dtype='uint8')*0

The following is more explicit, readable and efficient:

y_laser1 = np.zeros(nr_of_points, dtype='uint8')
y_laser2 = np.ones(nr_of_points, dtype='uint8')
y_laser3 = np.zeros(nr_of_points, dtype='uint8') # 2
y_laser_dead_zone = np.zeros(5*nr_of_points, dtype='uint8')

Hi @GasPatxo ,

I believe I can answer that question. [ I would describe myself as a semi-professional Python coder and a machine learning enthusiast. ]

So the difference between using np.ones(n) * 0 vs using np.zeros(n) is a subtle thing to understand. Telling you from my experience.

Lets say we have a variable initialized as var = np.zeros(5). You would get an array with five zeros. But you can never change this later in case you want them to be ones.
So, doing np.ones(5) * 0 will give you the opportunity to change it to something like np.ones(5) * 1 or np.ones(5) * 10 in the future. But in case you declared it as np.zeros(5), you will have to change it to np.ones(5) * N.

The subtle thing here is to not to change np.zeros() to np.ones() insetead use np.ones(n) * 0 for declaring zeros.

Hope I have solved your confusion. Let me know if I was helpful and made any sense!

Regards,
— Girish

Thanks for the reply!

However, I’m afraid I do not understand the differentiation you are showing to me. What does it mean that I cannot change x = np.zeros(5) later on?

I tried to play with it but saw nothing:

my-laptop:~$ python3
Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> (x := np.zeros(5))
array([0., 0., 0., 0., 0.])
>>> x[3] = 3.14
>>> x
array([0.  , 0.  , 0.  , 3.14, 0.  ])
>>> x *= 2
>>> x
array([0.  , 0.  , 0.  , 6.28, 0.  ])
>>> (x := np.ones(5))
array([1., 1., 1., 1., 1.])
>>> (x := np.ones(5)*15)
array([15., 15., 15., 15., 15.])

@GasPatxo ,

Ok, so you did not understand the “subtlety” in the point.
Let me get to the point straight.
You declare a zero array as np.ones(n) * 0 because you do not want to change this variable declaration every time during the code.

Do you want to change np.zeros(n) to np.ones() every now and then in your code?
(OR)
Rather, just keep np.ones() and make it zeros or non-zeros when you want?

It is simply the difference between changing function name calls and basic math. Instead of typing out z, e, r, o, s and o, n, e, s every time you want to change the variable value.

I am afraid I cannot explain it any simpler!

Regards,
Girish

If it is for the matter that one does not know which value is desired in a variable, why not use np.full() instead? For example:

>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

In any case, we know for certain that we want those variables to be arrays of ones and zeros. What you say might make sense while developing the code but in that case its a working example, the filling value must not change. So why make it complicated and difficult to read when you can use the provided functions by numpy?

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
1 Like

@GasPatxo ,

I totally agree with your point. It is valid.

But reading np.zeros() or np.ones() is much easier to understand than using np.full(). If you happen to be the person who have not used np.full() before and knowing about it for the first time, you will be inclined to check what that function is. Besides that, np.full() is actually more confusing than zeros or ones. The aim of np.full() is to fillup an array with values, just like how zeros and ones also does. But I prefer, reading zeros or ones instead of full. One might come up with multiple function which does the same thing, but at the end of the day, it is mathematical ease which makes the program understand, after all, every algorithm is a mathematical expression of some sort.

Well, I just explained what I feel is reasonable. If you like to use np.full() or any similar function, go ahead! But from my work experience so far, I have seen people initialize arrays like this either with zeros or ones. zeros() where they are definitely zeros and respectively for ones. But mostly ones() * n where initial value is unknown/undecided.

Regards,
Girish

This topic was automatically closed after 41 hours. New replies are no longer allowed.