我正在尝试将numpy数组重新绑定到新网格上。在这种特殊情况下,我试图将功率谱重新划分为对数网格,以便数据以对数方式均匀分布以用于绘图目的。
使用np.interp
进行直线插值时,会导致部分原始数据被完全忽略。使用digitize
得到我想要的结果,但是我必须使用一些丑陋的循环才能使它工作:
xfreq = np.fft.fftfreq(100)[1:50] # only positive, nonzero freqs
psw = np.arange(xfreq.size) # dummy array for MWE
# new logarithmic grid
logfreq = np.logspace(np.log10(np.min(xfreq)), np.log10(np.max(xfreq)), 100)
inds = np.digitize(xfreq,logfreq)
# interpolation: ignores data *but* populates all points
logpsw = np.interp(logfreq, xfreq, psw)
# so average down where available...
logpsw[np.unique(inds)] = [psw[inds==i].mean() for i in np.unique(inds)]
# the new plot
loglog(logfreq, logpsw, linewidth=0.5, color='k')
有没有更好的方法来实现这个numpy?我只是更换内联循环步骤而感到满意。
答案 0 :(得分:1)
您可以使用bincount()
两次来计算每个分档的平均值:
logpsw2 = np.interp(logfreq, xfreq, psw)
counts = np.bincount(inds)
mask = counts != 0
logpsw2[mask] = np.bincount(inds, psw)[mask] / counts[mask]
或两次使用unique(inds, return_inverse=True)
和bincount()
:
logpsw4 = np.interp(logfreq, xfreq, psw)
uinds, inv_index = np.unique(inds, return_inverse=True)
logpsw4[uinds] = np.bincount(inv_index, psw) / np.bincount(inv_index)
或者如果您使用Pandas:
import pandas as pd
logpsw4 = np.interp(logfreq, xfreq, psw)
s = pd.groupby(pd.Series(psw), inds).mean()
logpsw4[s.index] = s.values