在xlwings中加速UDF

时间:2016-01-02 20:04:32

标签: python xlwings

我试图尝试来自Xlwings的一些功能。我想使用numpy中允许快速插值的常用函数(numpy.interp)。

@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行),随机数为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 [...]工作.value = 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

1 个答案:

答案 0 :(得分: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)。