2013-03-09 107 views
2

我想將一個numpy數組重新加入一個新的網格。在這個特定的情況下,我試圖將一個功率譜重新映射到一個對數網格上,以便數據以對數方式均勻間隔以用於繪圖目的。Numpy:通過平均值的regrid?

使用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的做到這一點一個更好的辦法嗎?我只會滿足於更換內聯循環步驟。

回答

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) 

或者,如果您使用熊貓:

import pandas as pd 
logpsw4 = np.interp(logfreq, xfreq, psw) 
s = pd.groupby(pd.Series(psw), inds).mean() 
logpsw4[s.index] = s.values 
+0

很酷。 'pandas'對於這個用途會有點沉重,所以我喜歡'bincount'方法。我不認爲這個解決方案可以用於中位數,但是 - 你能想出一種方法來做中位數/百分位數嗎? – keflavich 2013-03-10 16:01:15