Numpy деление на 0 обходной путь - PullRequest
0 голосов
/ 13 мая 2018

Допустим, у меня есть два массива

x = [1,2,3]
y = [0,1,0]

Мне нужно разделить массивы поэлементно, используя, таким образом, numpy.Моя проблема заключается в «безопасном разделении».при выполнении:

np.divide(x,y).tolist()

я получаю вывод:

[0.0, 2.0, 0.0]

Моя проблема с этим заключается в том, что мне нужно вернуть элемент, который не равен 0, когда он делится на 0, делаяидеальный результат:

[1.0, 2.0, 3.0]

Есть ли обходной путь, чтобы сделать это, используя Numpy?Определяя вручную функцию для этого, существует ли какой-либо оптимизированный способ сделать это, не создавая пользовательскую функцию деления (например, следующую) и не используя ее для каждой пары элементов?

def mydiv(x, y):
if y == 0:
    return x
else:
    return x / y

ПРИМЕЧАНИЕ: причина, по которой меня беспокоит оптимизация, заключается в том, что она будет выполняться в облаке, поэтому ресурсы ограничены, и при наличии более 300 массивов элементов это не кажется оптимальным.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Простой трюк, который вы можете использовать:

x / (y + (y==0))

В действии:

x = np.array([1, 5, 3, 7])
y = np.array([0, 2, 0, 4])

print(x / (y + (y==0)))

# [1.   2.5  3.   1.75]

Тайминги:

def chrisz(x, y):
  return x/(y+(y==0))

def coldspeed1(x, y):
  m = y != 0
  x[m] /= y[m]
  return x

def coldspeed2(x, y):
  m = ~(y == 0)
  x[m] /= y[m]
  return x

def coldspeed3(x, y):
  m = np.flatnonzero(y)
  x[m] /= y[m]
  return x

Результаты:

In [33]: x = np.random.randint(10, size=10000).astype(float)

In [34]: y = np.random.randint(3, size=10000).astype(float)

In [35]: %timeit chrisz(x, y)
29.4 µs ± 601 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [36]: %timeit coldspeed1(x, y)
173 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [37]: %timeit coldspeed2(x, y)
184 µs ± 1.36 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [38]: %timeit coldspeed3(x, y)
179 µs ± 2.68 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
0 голосов
/ 13 мая 2018

Самый простой / быстрый способ сделать это - просто разделить значения, соответствующие ненулевому y-значению.

x = [1, 2, 3]
y = [0, 1, 0]

x, y = [np.array(arr, dtype=float) for arr in (x, y)]

m = y != 0  # ~(y == 0) # np.flatnonzero(y)
x[m] /= y[m]

print(x)
array([1., 2., 3.])
...