大熊猫迭代更新列值

时间:2018-07-20 19:30:51

标签: python performance pandas numpy iteration

我的熊猫系列如下:

a = pd.Series([a1, a2, a3, a4, ...])

,我想根据以下规则创建另一个熊猫系列:

b = pd.Series(a1, a2+a1**0.8, a3 + (a2 + a1**0.8)**0.8, a4 + (a3 + (a2 + a1**0.8)**0.8)**0.8, ...)

这可以通过迭代来实现,但是我有一个很大的数据集(数百万条记录),并且我必须执行数千次操作(出于优化目的)。我需要非常快地执行此操作。我有没有可能通过使用pandasnumpy内置函数来实现这一点?

4 个答案:

答案 0 :(得分:1)

关于这些问题,您需要了解的重要一点是,您现在处于悖论上。这意味着您想利用向量化和非向量化(例如线程化或并行化)优势。

在这种情况下,您可以尝试以下一种/一些选项:

  1. 更改数据结构的类型。

  2. 重新考虑您的问题,看看是否有可能完全以向量化的方式(最好)解决此问题

  3. 仅使用基于非矢量化的方法,但会牺牲内存等其他东西。

答案 1 :(得分:1)

您可以使用numba并尝试制作最简单的性能迭代版本,而不是与问题的根本迭代性质作斗争:

@numba.jit(nopython=True)
def epow(vec, p):
    out = np.zeros(len(vec))
    out[0] = vec[0]
    for i in range(1, len(vec)):
        out[i] = vec[i] + (out[i-1])**0.8
    return out

这给了我

In [148]: a1, a2, a3, a4 = range(1, 5)

In [149]: a1, a2+a1**0.8, a3 + (a2 + a1**0.8)**0.8, a4 + (a3 + (a2 + a1**0.8)**0.8)**0.8
Out[149]: (1, 3.0, 5.408224685280692, 7.858724574530816)

In [150]: epow(pd.Series([a1, a2, a3, a4]).values, 0.8)
Out[150]: array([1.        , 3.        , 5.40822469, 7.85872457])

以及更长的系列:

In [151]: s = pd.Series(np.arange(2*10**6))

In [152]: %time epow(s.values, 0.8)
CPU times: user 512 ms, sys: 20 ms, total: 532 ms
Wall time: 531 ms
Out[152]: 
array([0.00000000e+00, 1.00000000e+00, 3.00000000e+00, ...,
       2.11487244e+06, 2.11487348e+06, 2.11487453e+06])

答案 2 :(得分:0)

您可以使用递归函数,它将在O(log(n))时间运行

:dev-overrides {}

答案 3 :(得分:0)

使用循环

new_series=[]
cur_val=0
for ele in a:
    cur_val=ele+cur_val**0.8
    new_series.append(cur_val)