2016-01-02 34 views
0

我試圖從Xlwings實驗一些功能。我想使用允許快速插入的numpy的常用函數(numpy.interp)。在xlwings中加速UDF

@xlfunc 
def interp(x, xp,yp): 
    """Interpolate vector x on vector (xp,yp)""" 
    y=np.interp(x,xp,yp) 
    return y 

@xlfunc 
def random(): 
    """Returns a random number between 0 and 1""" 
    x=np.random.randn() 
    return x 

例如,我創建兩個矢量(XP,YP)像這樣(在Excel) 800行

First Column Second Column 
0 =random() 
1 =random() 
2 =random() 
3 =random() 
4 =random() 
5 =random() 
[...] 

在我創建另一個向量(60行)的第三列,隨機數bewteen 0和800(按升序排列) 這給了我這樣的事情:

Third Column  
17.2  
52.6  
75.8  
[...] 

我想第三列插值到第一列。所以

Fourth Column  
=interp(C1,A1:A800,B1:B800)  
=interp(C2,A1:A800,B1:B800)  
=interp(C3,A1:A800,B1:B800)  
[...] 

這很容易做到這一點。但是如果我有10列或更多的列插入它可能需要太多的時間。我相信有更好的方法來做到這一點。一個主意 ?

感謝您的幫助!

編輯:

我試過,但在不工作 「xw.Range [...]值= Y」

@xw.xlfunc 
def interpbis(x, xp,yp): 
    """Interpolate scalar x on vector (xp,yp)""" 
    thisWB=xw.Workbook.active() 
    thisSlctn=thisWB.get_selection(asarray=True) 
    sheet=thisSlctn.xl_sheet.name 
    r = thisSlctn.row 
    c = thisSlctn.column 
    y=np.interp(x,xp,yp) 
    xw.Range(sheet,(r,c)).value=y 
    return None 
+0

您是否嘗試過並發現一些實際的性能問題? –

+0

確實如此。實際上,當我啓動所有計算時,只要在VBA中運行(我想這是因爲UDF被構建爲在每個單元格上逐個運行)。也許如果我可以使用範圍,它會更快,但我不知道如何輕鬆做到這一點。 – Coolpix

+0

[編輯]如果我可以得到活動單元格地址,我可以像Range(ActiveCell).table = ar一樣使用數組和resut來做類似的事情? – Coolpix

回答

1

簡短的回答是:使用Excel中的數組功能。

長的答案是: 首先,更新到xlwings v0.6.4(否則我將要顯示的random()將不起作用)。然後改變你的功能如下:

from xlwings import Application, Workbook, xlfunc 
import numpy as np 

@xlfunc 
def interp(x, xp, yp): 
    """Interpolate vector x on vector (xp,yp)""" 
    y = np.interp(x, xp, yp) 
    return y[:, np.newaxis] # column orientation 

@xlfunc 
def random(): 
    """Returns a random number between 0 and 1""" 
    app = Application(Workbook.caller()) 
    # We shall make this easier in a future release (getting the array dimensions) 
    r = app.xl_app.Caller.Rows.Count 
    c = app.xl_app.Caller.Columns.Count 
    x = np.random.randn(r, c) 
    return x 

現在使用數組公式在Excel中所描述的hereCtrl+Shift+Enter)。

+0

非常感謝,這很好:)而且它非常快 – Coolpix

+0

我也試過類似的東西,但是我在Range.Value行上得到了「Erreur Automation」。 (xp,yp): 「」「在矢量(xp,yp)上插值標量x」「」 thisWB = xw.Workbook.active() thisSlctn = thisWB.get_selection(asarray = True) y = np.interp(x,xp,yp) thisSlctn.value = y – Coolpix

+0

'thisSlctn.xl_sheet.name'返回pywin32或appscript中的對象(取決於您的平臺) 。你將不得不在你的示例中用'thisWB.name'替換它。 –