Выборка последовательности фиксированной длины из массива numpy

У меня есть матрица данных a и список индексов, хранящихся в массиве idx. Я хотел бы получить данные длиной 10, начиная с каждого из индексов, определенных idx . Прямо сейчас я использую цикл for для достижения этой цели. Но это очень медленно, так как мне приходится делать выборку этих данных около 1000 раз за итерацию. Ниже приведен минимальный рабочий пример.

import numpy as np
a = np.random.random(1000)
idx = np.array([1, 5, 89, 54])

# I want "data" array to have np.array([a[1:11], a[5:15], a[89:99], a[54:64]])
# I use for loop below but it is slow
data = []

for id in idx:
    data.append(a[id:id+10])  
data = np.array(data)

Можно ли как-то ускорить этот процесс? Спасибо.

Обновлено: Мой вопрос отличается от заданного здесь. В вопросе размер фрагментов является случайным, в отличие от фиксированного размера фрагмента в моем вопросе. Существуют и другие различия. Мне не нужно использовать весь массив a, и элемент может встречаться более чем в одном фрагменте. Мой вопрос не обязательно «разделяет» массив.

Я предполагаю, что a это единицы для целей вопроса, верно?

Ivan 12.12.2020 09:44

@ Иван, ха-ха, да. Я отредактировал его, чтобы теперь он имел случайные значения.

learner 12.12.2020 09:44

это сложнее, потому что есть перекрывающиеся разделы! Если вы сделаете np.split(a, idx), вы разделите массив на индексы 1, 5 оставив вас с [array of size 1, array of size 4, ..., что не является желаемым результатом.

Ivan 12.12.2020 09:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
3
651
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

(Благодаря предложению @MadPhysicist)

Это должно работать:

a[idx.reshape(-1, 1) + np.arange(10)]

Выход: Форма (L,10), где L - длина idx

Примечания:

  1. Это не проверяет ситуации выхода за границы индекса. Я полагаю, что сначала легко убедиться, что idx не содержит таких значений.

  2. Использование np.take(a, idx.reshape(-1, 1) + np.arange(10), mode='wrap') является альтернативой, которая будет обрабатывать индексы за пределами границ, оборачивая их вокруг a. Передача mode='clip' вместо mode='wrap' обрезает лишние индексы до последнего индекса a. Но тогда у np.take(), вероятно, была бы совершенно другая производительность. характеристика / характеристика масштабирования.

Я думаю, что было бы быстрее отсортировать индекс, особенно для коротких массивов. +1 в любом случае

Mad Physicist 12.12.2020 10:34

Кроме того, вам действительно не нужно изменять форму и транспонировать. Выходной массив представляет собой форму индекса. idx.reshape(-1, 1) + np.arange(10) достаточно

Mad Physicist 12.12.2020 10:36

@MadPhysicist - Спасибо, отредактировано с упрощением.

fountainhead 12.12.2020 10:44

Мы можем увидеть изменения в истории редактирования. Не нужно отмечать «редактировать» и «обновить» в вопросах и ответах. Это распространенное заблуждение среди начинающих авторов, что люди хотят видеть что-то кроме вашего отточенного продукта.

Mad Physicist 12.12.2020 10:47

Другие вопросы по теме