我有一个值数组和一个元组列表,表示需要从该数组中选择哪些索引。 (以元组表示音频阵列的哪个部分是语音。)我在考虑使用选择掩码:
import numpy as np
# sample data
arr = np.array([.3, .4, .5, -.2, -.1, .7, .9])
selection_idx = [(0, 3), (5,7)]
# unknown: how to efficiently selection_idx -> mask?
mask = [0, 1, 2, 5, 6] # or
mask = [True, True, True, False, False, True, True]
# desired result 1
arr[mask]
# Out: array([0.3, 0.4, 0.5, 0.7, 0.9])
Numpy本身仅限于numpy.arange
(据我所知)以生成规则的间隔序列。但是,熊猫具有numpy.arange
对象,可以使用诸如pandas.IntervalArray
的有用功能来创建该对象。用代码术语是:
pandas.IntervalArray
.from_tuples
对象转换为一个numpy数组(导致Goal下的.from_tuples
吗?import pandas as pd
pd.arrays.IntervalArray.from_tuples(selection)
# Out:
# <IntervalArray>
# [(0, 3], (5, 7]]
# Length: 2, closed: right, dtype: interval[int64]
用于我的用例,那还有什么其他方法? (在我的实际情况下,不规则元组的列表每个数组超过1000个(带有10.000个数组),因此我正在寻找一种比循环和IntervalArray
更有效的方法)一个想法是使用列表理解和扁平化:
mask
这可以解决您的问题,尽管我相信Numpy中可能有一个我不知道的语法:
IntervalArray
[基本上,它是通过拆开每个元组并使用itertool的numpy.append
将所有内容合并为一个列表来获得列表的。剩下的就是使用numpy的索引来获取您的结果。
注意,如果您有布尔值,可以使用numpy的numpy.append
来获取输出:
mask = [c for a,b in selection_idx for c in range(a,b)]
print(arr[mask])
[0.3 0.4 0.5 0.7 0.9]
加入相应的from itertools import chain
arr = np.array([.3, .4, .5, -.2, -.1, .7, .9])
selection_idx = [(0, 3), (5,7)]
m = list(chain.from_iterable(range(a,b) for a,b in selection_idx))
print(m)
# [0, 1, 2, 5, 6]
arr[m]
array([0.3, 0.4, 0.5, 0.7, 0.9])
很容易:
chain.from_iterable
我看不到compress构造提供任何性能优势的证据。该显示看起来就像来自输入元组的经过精心处理的属性。