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

Я пытаюсь лучше использовать функции и методы numpy для более быстрого запуска моих программ на python.

Я хочу сделать следующее:

Я создаю массив 'a' как:

a=np.random.randint(-10,11,10000).reshape(-1,10) 

а.форма: (1000,10)

Я создаю другой массив, который принимает только первые два столбца в массиве a

b=a[:,0:2] 

б, форма: (1000,2)

теперь я хочу создать массив c, содержащий 990 строк, содержащих сглаженные фрагменты из 10 строк массива «b». Таким образом, первая строка массива «c» будет иметь 20 столбцов, которые представляют собой сглаженный фрагмент от 0 до 10 строк массива «b». Следующая строка массива «c» будет иметь 20 столбцов сглаженных строк с 1 по 11 массива «b» и т. д.

Я могу сделать это с помощью цикла for. Но я хочу знать, есть ли более быстрый способ сделать это, используя функции и методы numpy, такие как шаги или что-то еще.

Спасибо за ваше время и вашу помощь.


person Ghanshyam Bhat    schedule 11.05.2020    source источник


Ответы (1)


Это перебирает сдвиги, а не строки (цикл размером 10):

N = 10
c = np.hstack([b[i:i-N] for i in range(N)])  

Объяснение: b[i:i-N] — это строки b от i до m-(N-i) (исключая саму m-(N-i)), где m — количество строк в b. Затем np.hstack складывает эти выбранные подмассивы по горизонтали (стеки b[0:m-10], b[1:m-9], b[2:m-8],..., b[10:m]) (как объясняет вопрос).

c.форма: (990, 20)

Также я думаю, что вы можете искать форму (991, 20), если хотите включить все окна.

вы также можете использовать шаги, но если вы хотите выполнять над ним операции, я бы не советовал этого делать, поскольку с ними сложно работать с памятью. Вот решение для шагов, если вы настаиваете:

from skimage.util.shape import view_as_windows
c = view_as_windows(b, (10,2)).reshape(-1, 20)

с.форма: (991, 20)

Если вам не нужна последняя строка, просто удалите ее, вызвав c[:-1].
Аналогичное решение применимо к функции as_strides numpy (в основном они работают одинаково, не уверен в их внутренностях).

ОБНОВЛЕНИЕ: если вы хотите найти уникальные значения и их частоты в каждой строке c, вы можете сделать следующее:

unique_values = []
unique_counts = []
for row in c:
  unique, unique_c = np.unique(row, return_counts=True)
  unique_values.append(unique)
  unique_counts.append(unique_c)

Обратите внимание, что массивы numpy должны быть прямоугольными, что означает, что количество элементов в каждой (размерной) строке должно быть одинаковым. Поскольку разные строки в c могут иметь разное количество уникальных значений, вы не можете создать массив numpy для уникальных значений каждой строки (альтернативой было бы создание структурированного массива numpy). Поэтому решение состоит в том, чтобы создать список/массив массивов, каждый из которых включает уникальные значения разных строк в c. unique_values — это список массивов уникальных значений, а unique_counts — их частота в том же порядке.

person Ehsan    schedule 11.05.2020
comment
Если бы я сейчас захотел найти уникальные значения и их частоту в каждой строке массива c, как вы это сделаете без циклов for или сделаете это гораздо быстрее, чем для стандартных циклов for, которые бы перебирали всю длину массива. Спасибо за вашу помощь - person Ghanshyam Bhat; 12.05.2020
comment
@GhanshyamBhat всегда пожалуйста. Если это решило вашу проблему, пожалуйста, примите его, чтобы другие тоже нашли его полезным. Ваш следующий вопрос - это другой вопрос. Я добавлю ответ к этому решению. Как бы вы хотели, чтобы в каждой строке сохранялись уникальные значения и частоты? поскольку он не может быть прямоугольным (уникальные значения для каждой строки могут быть разными). Один из способов — включить все числа и установить частоту 0 для отсутствующих в каждой строке. - person Ehsan; 12.05.2020
comment
Я добавил версию цикла for в сообщение, если вы не хотите определить способ преобразования вашего вывода в структурированный массив, это трудно сделать без циклов. Даже выполнение этого любым другим способом не должно быть значительно быстрее, чем цикл, потому что разные строки должны находить уникальные элементы отдельно. - person Ehsan; 12.05.2020
comment
Спасибо за ваше обновление. Я хотел бы иметь новый массив с уникальными значениями и их частотой один за другим в одной строке для каждой строки в c. Я очень ценю, что вы нашли время, чтобы ответить на мой вопрос. Большое спасибо. Кстати, я хотел бы понять логику вашего ответа для создания массива c. Непонятно, как функция hstack работает со всем массивом, если применяется только np.hstack([b[i:i-N] for i in range(N)]) с N=10. Спасибо еще раз - person Ghanshyam Bhat; 12.05.2020
comment
когда я попробовал ваш ответ для строки в c: unique_values, unique_counts = np.unique(row, return_counts=True), он не сгенерировал массив со строками, содержащими уникальные значения и их частоты. Он просто дал два массива с уникальными значениями и частотами только для одной из строк в c - не уверен, какая строка - возможно, первая или последняя строка - person Ghanshyam Bhat; 12.05.2020
comment
@GhanshyamBhat С удовольствием. Я обновлю пост с дополнительным объяснением. Тем временем stackoverflow.com/help/accepted-answer поможет вам лучше познакомиться с SO и узнать, как принять ответ. . Добро пожаловать в СО. - person Ehsan; 12.05.2020