Лучшие практики для расширения списка (эффективности) в python - PullRequest
2 голосов
/ 11 февраля 2020

Я работаю с большими наборами данных. Я пытаюсь использовать библиотеку NumPy, где я могу, или функции python для эффективной обработки наборов данных (например, L C).

Сначала я найду соответствующие индексы:

dt_temp_idx = np.where(dt_diff > dt_temp_th)

Затем я хочу создать маску, содержащую для каждого индекса последовательность, начиная с индекса до конечного значения, я попытался:

mask_dt_temp = [np.arange(idx, idx+dt_temp_step) for idx in dt_temp_idx]

и:

  mask_dt_temp = [idxs for idx in dt_temp_idx for idxs in np.arange(idx, idx+dt_temp_step)]

но это дает мне исключение:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Пример ввода:

indexes = [0, 100, 1000]

Пример вывода со стоп-значениями после 10 целых чисел из каждого индекса:

list = [0, 1, ..., 10, 100, 101, ..., 110, 1000, 1001, ..., 1010]

1) Как я могу решить это? 2) Это лучшая практика?

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Использование масок (логических массивов) является эффективным, а также экономит память и производительность. Мы будем использовать SciPy's binary-dilation для расширения пороговой маски.

Вот пошаговая установка и запуск решения -

In [42]: # Random data setup
    ...: np.random.seed(0)
    ...: dt_diff = np.random.rand(20)
    ...: dt_temp_th = 0.9

In [43]: # Get mask of threshold crossings
    ...: mask = dt_diff > dt_temp_th

In [44]: mask
Out[44]: 
array([False, False, False, False, False, False, False, False,  True,
       False, False, False, False,  True, False, False, False, False,
       False, False])

In [45]: W = 3 # window size for extension (edit it according to your use-case)

In [46]: from scipy.ndimage.morphology import binary_dilation

In [47]: extm = binary_dilation(mask, np.ones(W, dtype=bool), origin=-(W//2))

In [48]: mask
Out[48]: 
array([False, False, False, False, False, False, False, False,  True,
       False, False, False, False,  True, False, False, False, False,
       False, False])

In [49]: extm
Out[49]: 
array([False, False, False, False, False, False, False, False,  True,
        True,  True, False, False,  True,  True,  True, False, False,
       False, False])

Сравнить mask против extm, чтобы увидеть, как происходит расширение.

Как мы видим, пороговое значение mask расширяется на размер окна W с правой стороны, как и ожидаемая маска вывода extm. Это можно использовать для маскировки входных данных в массиве: dt_diff[~extm] для имитации удаления / удаления элементов из входных данных, следующих за boolean-indexing или наоборот dt_diff[extm] для имитации выбора этих элементов.

Альтернативы с функциями NumPy

Альтернатива # 1

extm = np.convolve(mask, np.ones(W, dtype=int))[:len(dt_diff)]>0

Альтернатива # 2

idx = np.flatnonzero(mask)
ext_idx = (idx[:,None]+ np.arange(W)).ravel()

ext_mask = np.ones(len(dt_diff), dtype=bool)
ext_mask[ext_idx[ext_idx<len(dt_diff)]] = False

# Get filtered o/p
out = dt_diff[ext_mask]
0 голосов
/ 11 февраля 2020

dt_temp_idx является массивом numpy, но все еще итерацией Python, поэтому вы можете использовать старый добрый Python список понимания:

lst = [ i for j in dt_temp_idx for i in range(j, j+11)]

Если вы хотите справиться с перекрытиями последовательностей и сделайте его обратно массивом np.array, просто сделайте:

result = np.array({i for j in dt_temp_idx for i in range(j, j+11)})

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

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