我在伪Python代码中遇到以下情况,为了优化起见,需要为此找到一种矢量化解决方案,因为我要处理成千上万的语音分析条目,并且嵌套循环是不可行的。我想知道如何对不同大小的数组进行条件检查的矢量化……例如,我知道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)
什么是解决此问题的好方法?我对矢量操作还比较陌生,并且已经为此花了好几个小时苦苦挣扎,但收效甚微。
答案 0 :(得分:0)
查看每个单词的所有可能音素将不会缩放。完成的工作量高于需要的工作量。使用任意数量的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