Numpy: установить false там, где что-либо слева является ложным - PullRequest
0 голосов
/ 24 декабря 2018

TLDR;Как мне установить значения в массиве NumPy в зависимости от значений в столбцах слева от каждого значения ...?

Я выполняю некоторые симуляции, где я прогнозирую показатели выживаемости, но ниже приводится суть того, что япытаюсь сделать.Я предсказываю кучу дискретных переживаний во времени, представленных как Истина и Ложь.Каждая строка представляет собой симуляцию, а каждый столбец - это момент времени (т. Е. Столбец 0 - это первый момент времени, столбец 1 - после этого)

mc = (8, 4)
survival = np.random.random(mc) > np.random.random(mc)
survival

Это даст мне вывод, подобный этому.

array([[False,  True,  True, False],
       [True,  False,  True, False],
       [ True, True,  True,  True], ...

Но если что-то умирает в первый момент времени, оно мертво навсегда.Таким образом, мой вывод должен быть:

array([[False,  False,  False, False],
       [True,  False,  False, False],
       [ True, True,  True,  True], ...

Итак, для ряда я хочу установить все False справа от первого False, которое я найду.Есть ли способ сделать это без двух вложенных циклов?Я ищу лучший подход, но пытаюсь понять, смогу ли я сделать это с помощью встроенных функций.

Ответы [ 4 ]

0 голосов
/ 24 декабря 2018

Старайтесь не использовать чистые циклы for при работе с пустыми массивами.

Используйте взамен cumulative product против axis=1

arr.cumprod(1).astype(np.bool)
0 голосов
/ 24 декабря 2018
>>> mc = (8, 4)
>>> survival = np.random.random(mc) > np.random.random(mc)
>>> survival
array([[ True,  True,  True,  True],
       [ True, False, False,  True],
       [ True, False,  True,  True],
       [ True, False,  True, False],
       [False,  True, False, False],
       [ True,  True, False,  True],
       [ True,  True, False, False],
       [False, False,  True,  True]])

и

>>> death = [x.tolist().index(False) if False in x else -1 for x in survival]
>>> [s[ : d].tolist() + [False] * (survival.shape[1] - d) if d != -1 else s.tolist() for s, d in zip(survival, death)]
[[True, True, True, True],
 [True, False, False, False],
 [True, False, False, False],
 [True, False, False, False],
 [False, False, False, False],
 [True, True, False, False],
 [True, True, False, False],
 [False, False, False, False]]
0 голосов
/ 24 декабря 2018

Существует совершенный инструмент :

np.logical_and.accumulate(survival,axis=1)

Пример:

array([[False,  True, False,  True],
       [ True,  True, False,  True],
       [False,  True,  True,  True],
       [False,  True, False, False],
       [ True, False, False, False],
       [False,  True,  True,  True],
       [False, False,  True, False],
       [False, False,  True,  True]])

=>
array([[False, False, False, False],
       [ True,  True, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [ True, False, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False, False]])
0 голосов
/ 24 декабря 2018

Используя np.argwhere:

import numpy as np


bob = np.array([[True,True,False,True,True],[True,True,False,True,True],[False,True,True,True,True],[True,True,False,True,True],[False,True,True,True,True]]) 

for arr in np.argwhere(bob == False):
    bob[arr[0],arr[1]:] = False

вышеупомянутый argwhere возвращает для каждого экземпляра false row,column, я использую эти значения, чтобы установить остаток строки в false (после каждоголожь).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...