python - Pandas 中的线性组合函数
问题描述
给定一个像这样的 Pandas 数据框:
from datetime import datetime
test = pd.DataFrame([
{'id': 1, 'date': datetime.fromisoformat('2016-01-01'), 'a': 1},
{'id': 1, 'date': datetime.fromisoformat('2016-01-02'), 'a': 2},
{'id': 1, 'date': datetime.fromisoformat('2016-01-03'), 'a': 3}]
)
我正在使用线性组合 Python 函数:
def lin_comb(v1, v2, beta=0.9):
return beta*v1 + (1-beta)*v2
lin_comb
根据a
具有以下值的列生成列:
id date a lin_comb
0 1 2016-01-01 1 1.000000
1 1 2016-01-02 2 1.099609
2 1 2016-01-03 3 1.290039
例如,上面最后一行的值是通过以下表达式计算的:
(1 * 0.9 + 2 * 0.1) * 0.9 + 3 * 0.1 = 1.29
这是整个可执行代码:
def lin_comb(v1, v2, beta=0.9): return beta*v1 + (1-beta)*v2
from datetime import datetime
test = pd.DataFrame([
{'id': 1, 'date': datetime.fromisoformat('2016-01-01'), 'a': 1},
{'id': 1, 'date': datetime.fromisoformat('2016-01-02'), 'a': 2},
{'id': 1, 'date': datetime.fromisoformat('2016-01-03'), 'a': 3}]
)
lin_com_list = []
c = 0.
for a in test['a']:
c = lin_comb(c or a, a, 0.9)
lin_com_list.append(c)
test['lin_comb'] = lin_com_list
我的问题:Pandas 中是否有内置函数可以生成与上述相同的输出?
我问的原因主要是性能。当您对数百万条记录执行此功能时,此代码非常慢。
解决方案
我认为 pandas 中没有用于这种递归操作的内置函数。但我认为这是一个很好的案例numba。我是新手,所以也许有更好的方法来做到这一点,但想法是:
from numba import jit
@jit
def numba_comb(arr_in, beta=0.9):
arr_out = np.zeros_like(arr_in)
c = 0.
for i in range(arr_in.shape[0]):
a = arr_in[i]
c = beta*(c or a) + (1-beta)*a
arr_out[i] = c
return arr_out
比较
def lin_comb(v1, v2, beta=0.9): return beta*v1 + (1-beta)*v2
def list_comb (ser, beta=0.9):
lin_com_list = []
c = 0.
for a in ser:
c = lin_comb(c or a, a, beta)
lin_com_list.append(c)
return lin_com_list
然后它给出:
test = pd.DataFrame({'a':range(1, 10000)})
# list solution
%timeit list_comb (test['a'], 0.9)
#3.51 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# numba
%timeit numba_comb(test['a'].to_numpy().astype(float), 0.9)
#63.8 µs ± 990 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
#same result
print ((np.array(list_comb (test['a']))
== numba_comb(test['a'].to_numpy().astype(float), 0.9)).all())
#True
推荐阅读
- android - 片段旋转上带有edittext的saveInstanceState不起作用
- c++ - 从 CDC 创建 CBitmap?
- angular - 如何在 Angular 应用程序启动之前获取提供者数据
- graphql - GraphQL/Apollo Server 上同一字段的多个输入
- node.js - 通过利用 Mongoose 中的 _v 键对 mongoose 中的用户输入进行版本控制
- c# - 我怎么做才能让 catch 停止循环并回到循环的开头
- r - 如何对 R data.table 中的变量词进行排序?
- r - 如何将字符转换为数值并根据分类列对它们进行平均?
- react-native - 如何在 useEffect 中使用事件监听器?
- html - 基于元组列表的 Flask 渲染选择