我有一个二维数组,其中每个元素都是一个傅立叶变换。我想对数转换“对数”。例如,让我们采用其中一个数组并将其命名为a
:
a = np.arange(0, 512)
# I want to split a into 'bins' defined by b, below:
b = np.array([0] + [10 * 2**i for i in range(6)]) # [0, 10, 20, 40, 80, 160, 320, 640]
我想做的事情与使用np.split
类似,除了我想根据数组b
将值拆分为“ bins”,使得所有a
之间的值[0,10)位于一个仓中,[10,20)之间的所有值都位于另一个仓中,等等。
我可以用某种复杂的for循环来做到这一点:
split_arr = []
for i in range(1, len(b)):
fbin = []
for amp in a:
if (amp >= b[i-1]) and (amp < b[i]):
fbin.append(amp)
split_arr.append(fbin)
我有很多要拆分的数组,这也很难看(只是我的看法)。有更好的方法吗?
答案 0 :(得分:4)
以下是使用np.split
的方法:
np.split(a, np.searchsorted(a,b))
如果您的数组a
未排序,请在上述命令之前对其进行排序:
a = np.sort(a)
np.searchsorted
在b
中找到要插入排序数组a
中的值的位置。换句话说,np.searchsorted
查找要拆分数组的位置。而且,如果您不希望开头有空数组,只需从0
中删除b
。
答案 1 :(得分:1)
首先,您可以使用列表理解来减少“丑陋”:
split_arr = [[amp for amp in a if (amp >= b[i-1]) and (amp < b[i])] for i in range(1, len(b))]
然后,您可以使用numpy快速并行化功能来应用相同的逻辑(这样做看起来更加干净):
split_arr = [a[(a >= b[i-1]) & (a < b[i])] for i in range(1, len(b))]
比较:
%timeit [[amp for amp in a if (amp >= b[i-1]) and (amp < b[i])] for i in range(1, len(b))]
1.29 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit [a[(a >= b[i-1]) & (a < b[i])] for i in range(1, len(b))]
35.9 µs ± 4.52 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)