Условия для элементов numpy массивов с разными размерами

У меня есть следующий случай в псевдо-коде Python, и мне нужно найти векторизованное решение для него в целях оптимизации, поскольку я имею дело с сотнями тысяч записей для анализа речи, а вложенные циклы for нежизнеспособны. Мне интересно, как я могу векторизовать условные проверки для массивов разных размеров ... Я знаю, например, о np.greater, но это поэлементная операция, которая не работает с массивами разных размеров.

words = [
    {'id': 0, 'word': 'Stu', 'sampleStart': 882, 'sampleEnd': 40571},
    {'id': 0, 'word': ' ', 'sampleStart': 40570, 'sampleEnd': 44540},
    {'id': 0, 'word': 'eyes', 'sampleStart': 44541, 'sampleEnd': 66590},
]

phonemes = [
    {'id': 0, 'phoneme': ' ', 'sampleStart': 0, 'sampleEnd': 881},
    {'id': 1, 'phoneme': 's', 'sampleStart': 882, 'sampleEnd': 7937},
    {'id': 2, 'phoneme': 't', 'sampleStart': 7938, 'sampleEnd': 11906},
    {'id': 3, 'phoneme': 'u', 'sampleStart': 11907, 'sampleEnd': 15433},
    {'id': 3, 'phoneme': ' ', 'sampleStart': 15434, 'sampleEnd': 47627},
    {'id': 3, 'phoneme': 'eye', 'sampleStart': 47628, 'sampleEnd': 57770},
    {'id': 3, 'phoneme': 's', 'sampleStart': 57771, 'sampleEnd': 66590},
]

associatedData = []
for w in words:
    startWord = w['sampleStart']
    endWord = w['sampleEnd']
    word = w['word']
    w_id = w['id']
    for p in phonemes:
        startPhoneme = p['sampleStart']
        endPhoneme = p['sampleEnd']
        phoneme = p['phoneme']
        p_id = p['id']
        if startPhoneme >= startWord and endPhoneme <= endWord:
            # I need to relate this data as it comes from 2 different sources
            # Some computations occur here that are too ling to reproduce here, this multiplication is just to give an example
            mult = startPhoneme * startWord
            associatedData.append({'w_id' : w_id, 'p_id': p_id, 'word' : word, 'phoneme' : phoneme, 'someOp': startWord})

# Gather associated data for later use:
print(associatedData)

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

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

sacuL 06.09.2018 19:52

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

kabanus 06.09.2018 19:58

Когда массивы различаются по размеру, обычно приходится работать с ними индивидуально. Если они не помещаются в один многомерный массив, вы не можете использовать более быстрые методы целого массива.

hpaulj 06.09.2018 20:06

Извинения, см. Отредактированный пост для более конкретного примера

Darien 06.09.2018 20:35
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
205
1

Ответы 1

Глядя на все возможные фонемы для каждого слова, масштаб не получится. Объем проделанной работы больше, чем нужно. С любым количеством words и phonemes всегда будут операции len(words) * len(phonemes) с этим подходом. Векторизация может ускорить это, но вместо этого лучше уменьшить саму сложность.

Лучше для каждого слова старайтесь смотреть только на несколько кандидатов фонем. Одним из решений может быть сохранение указателя на текущую фонему. С каждым новым словом повторяйте (локально, только вокруг указателя текущей фонемы) по диапазону совпадающих фонем.

Решение псевдокода:

# skip if already sorted
words = sorted(words, key=lambda x:x["sampleStart"])
phonemes = sorted(phonemes, key=lambda x:x["sampleStart"])

phoneme_idx = 0
for w in words:

    # go back until the earliest relevant phoneme
    while endtime(phonemes[phoneme_idx]) < starttime(w):
         phoneme_idx -= 1

    # evaluate all phonemes in range
    while endtime(phonemes[phoneme_idx]) <= starttime(w):
         # match and compute
         evavalute(phonemes[phoneme_idx], w)
         phoneme_idx += 1

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