Subarray как условие для numpy .where () - PullRequest
0 голосов
/ 25 марта 2020

Чтобы прояснить это заранее: я относительно новичок в python, и мои «навыки программирования» в основном связаны с MATLAB (то есть я могу использовать встроенные функции). Следовательно, я надеюсь, что мой вопрос не так глуп, как я думаю. То, что я еще не нашел ответа на это, означает, что я либо сам не понял свою проблему, либо что это действительно «что-то новое».

Достаточно шуток: я извлек массив из изображения в котором я сохранил значения пикселей вдоль линии регрессии, которую я предварительно определил по изображению, оставив массив numpy, такой как [0,0,0,...,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,...]. Из-за некоторого шума я получаю некоторые непреднамеренные по массиву, что приводит к моей проблеме: я хочу найти индекс первого значения, после которого я могу найти подмассив [1,1,1,1,1], например. Кажется, я не могу заставить numpy.where() сделать это, и я должен признать, что не имею абсолютно никакого представления о том, как заставить его работать эффективно. Поиск в подмассиве вручную с помощью al oop недостаточно эффективен, поэтому использование грубой силы также не работает для меня.

Есть ли способ решить эту проблему "pythoni c"? Если да, не могли бы вы предоставить более или менее подробное объяснение, чтобы я мог понять и воспроизвести его? Я хочу больше думать о «pythoni c», но я не могу понять, что такое «1014 *».

Ответы [ 2 ]

1 голос
/ 25 марта 2020

np.cumsum предоставляет только решение, конкретное c для этой проблемы; Я постараюсь найти более общее решение для любого типа паттернов. Вы можете подумать об этом как о проблеме соответствия строк. У вас есть большая строка (скажем, ваш массив 1 и 0) и определенный шум, который вы хотите найти, который составляет 11111. Более того, вы хотите найти тот индекс, в котором шаблон появляется впервые. Это можно легко сделать в одной строке кода несколькими способами.

import re

def find_idx_of_first_noise(A, N):
    return re.search(''.join(N.astype(str)),''.join(A.astype(str))).start()

A = np.array([0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1])
N = np.array([1,1,1,1,1])

print(find_idx_of_first_noise(A, noise))

Out:

7

A и N - это numpy массивы целых чисел, поэтому я ' m преобразует их в массивы строк с .astype(str). Затем я объединяю все массивы строк в одну строку, вызывая ''.join(). Таким образом, по сути, я запускаю строку: re.search('11111','0100100111111111').start(), которая находит 11111 в A и дает мне индекс его первого появления.

Еще один способ написания кода на pythoni c, который вы должны получить сверху из списка понятий. Я выполню вышеописанную задачу еще раз в одной строке кода:

print([i for i in range(len(A)-len(N)+1) if (A[i:i+len(N)]==N).all()][0])

Out:

7

Несмотря на удобство, списочные определения все еще являются методом грубой силы; это в основном для l oop внутри списка.

Теперь самый быстрый и самый быстрый метод pythoni c, на мой взгляд, это использовать tostring.

print(A.tostring().index(N.tostring())//A.itemsize)

Out:

7

Превратите массивы numpy в байтовые строки, затем используйте .index, чтобы найти положение любого шаблона / шума, который у вас есть. Разделите на размер предметов в A, и вы получите свой результат.

1 голос
/ 25 марта 2020

Используйте np.cumsum() и возьмите различия между индексами элементов 5.

import numpy as np
np.random.seed(456)  # Make results repeatable

arr= np.random.randint(2, size=100)

arr
# array([1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1,
#        1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1,
#        0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1,
#        1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0,
#        1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1])

cumulate = np.zeros(arr.shape[0]+1, dtype = np.int)
cumulate[1:] = arr.cumsum()   # First item in the array must be zero
diff = cumulate[5:]-cumulate[:-5]

cumulate
# array([ 0, 1,  2,  3,  4,  4,  5,  5,  5,  6,  6,  6,  7,  7,  8,  9,  9, 10,
#        11, 12, 12, 13, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17,
#        17, 17, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 21, 22, 23, 24, 25,
#        25, 25, 26, 26, 27, 27, 28, 28, 28, 29, 30, 30, 30, 30, 31, 32, 33,
#        34, 35, 36, 36, 36, 37, 38, 38, 38, 39, 39, 40, 41, 42, 42, 42, 42,
#        43, 44, 44, 45, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 52])

np.where( diff == 5 )
# (array([46, 65, 66]),)

np.where возвращает кортеж массивов, поэтому [0] [0] для получения требуемого индекса.

np.where(diff == 5)[0][0]
# 46
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...