2

我正在尝试将一个 numpy 数组重新网格到一个新网格上。在这种特定情况下,我试图将功率谱重新网格到对数网格上,以便数据以对数均匀分布以用于绘图目的。

使用直接插值执行此操作np.interp会导致某些原始数据被完全忽略。Usingdigitize得到了我想要的结果,但我必须使用一些丑陋的循环来让它工作:

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 中是否有更好的方法来实现这一点?只需替换内联循环步骤,我就会感到满意。

4

1 回答 1

1

您可以使用bincount()两次来计算每个 bin 的平均值:

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)andbincount()两次:

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
于 2013-03-10T06:12:19.677 回答