【发布时间】:2018-09-19 16:25:37
【问题描述】:
我想将函数逐行应用于如下所示的数据框:
name value
'foo' 2
'bar' 4
'bar' 3
'foo' 1
. .
. .
. .
'bar' 8
速度对我来说很重要,因为我在多个 90GB 数据集上进行操作,因此我一直在尝试对以下操作进行矢量化以在 df.apply 中使用:
以“名称”为条件,我想将“值”插入一个单独的函数,对结果执行一些算术运算,然后写入一个新列“输出”。类似的,
funcs = {'foo': <FunctionObject>, 'bar': <FunctionObject>}
def masterFunc(row):
correctFunction = funcs[row['name']]
row['output'] = correctFunction(row['value']) + 3*row['value']
df.apply(masterFunc, axis=1).
在我真正的问题中,我有 32 个不同的函数可以根据“名称”应用于“值”。这些单独的函数(fooFunc、barFunc、zooFunc 等)中的每一个都已经被矢量化了;它们是这样构建的 scipy.interp1d 函数:
separateFunc = scipy.interpolate.interp1d(x-coords=[2, 3, 4], y-coords=[3, 5, 7])
#separateFunc is now a math function, y=2x-1. use case:
y = separateFunc(3.5) # y == 6
但是,我不确定如何对 masterFunc 本身进行矢量化。似乎选择将哪个函数“拉出”以应用于“值”非常昂贵,因为它需要在每次迭代时进行内存访问(使用我当前将函数存储在哈希表中的方法)。然而,替代方案似乎只是一堆 if-then 语句,这似乎也无法向量化。如何加快速度?
为简洁起见,删除了重复部分的实际代码:
interpolationFunctions = {}
#the 'interpolate.emissionsFunctions' are a separate function which does some scipy stuff
interpolationFunctions[2] = interpolate.emissionsFunctions('./roadtype_2_curve.csv')
interpolationFunctions[3] = interpolate.emissionsFunctions('./roadtype_3_curve.csv')
def compute_pollutants(row):
funcs = interpolationFunctions[row['roadtype']]
speed = row['speed']
length = row['length']
row['CO2-Atm'] = funcs['CO2-Atm'](speed)*length*speed*0.00310686368
row['CO2-Eq'] = funcs['CO2-Eq'](speed)*length*speed*0.00310686368
return row
【问题讨论】:
-
通过像这样保持函数分离,除了使用 apply 之外几乎没有什么可做的。但是,根据功能的不同,您可以通过
numba使用jit执行某些操作。如果您愿意分享实际功能,您应该这样做。您也可以 cythonize,但同样,这取决于功能(我认为)。甚至分享其中的 2 或 3 个,以便我们进行演示。 -
嗨@piRSquared 感谢您的回复!我的单独函数是 scipy 插值函数(在原始问题中添加)。我可以用它做些什么吗?
-
我没有看到任何功能。
-
抱歉,刚刚添加完毕。每个单独的Func 都是根据预先存在的数据预先构建的; scipy.interpolate 将它们作为函数对象返回。
-
你所有的功能都是这样的吗?再给我看几张。对于通用函数对象,您可能不会得到一个简单的答案。但是我们也许可以对函数本身做一些事情。我当然可以重写一个插值函数。问题是,我们能否写出一个动态的。也许,我需要了解更多您的其他功能。
标签: python pandas scipy python-multiprocessing data-science