Обычно ответом на это является использование массива с плавающей точкой, а не массива произвольных объектов, а затем использование np.nan
вместо None
. NaN имеет четко определенную семантику для арифметики. (Кроме того, использование массива с плавающей точкой вместо объектов сделает ваш код значительно более эффективным с точки зрения времени и пространства.)
Обратите внимание, что вам не нужно вручную преобразовывать None
в np.nan
, если вы строите массив с явным dtype
из float
или np.float64
. Оба они эквивалентны:
>>> a = np.array([1.0,np.nan,2.0])
>>> a = np.array([1.0,None,2.0],dtype=float)
Это означает, что если по какой-то причине вам действительно нужны массивы произвольных объектов с действительным None
, вы можете сделать это, а затем преобразовать его в массив с плавающей точкой на лету, чтобы получить преимущества от NaN :
>>> a.astype(float) + b.astype(float)
В любом случае, в данном случае просто использования NaN недостаточно:
>>> a = np.array([1.0,np.nan,2.0])
>>> b = np.array([1.0,2.0,2.0])
>>> a + b
array([ 2., nan, 4.])
Это потому, что семантика NaN заключается в том, что результат любой операции с NaN возвращает NaN. Но вы хотите рассматривать это как 0.
Но это делает проблему легко решаемой. Самый простой способ решить это с помощью функции nan_to_num
:
>>> np.nan_to_num(a, 0)
array([1., 0., 2.0])
>>> np.nan_to_num(a, 0) + np.nan_to_num(b, 0)
array([2., 2., 4.])