Access the results of the previous calculation in the user function passed to the application ()

I work with Pandas in Python, and I would like to access the results of the previous calculation when applying a custom function to a series.

Like that:

import pandas

# How can I obtain previous_result?
def foo(value, previous_result = None):

    # On the first iteration there is no previous result
    if previous_result is None:
        previous_result = value

    return value + previous_result

series = pandas.Series([1,2,3])
print(series.apply(foo))

It can also be generalized to "How do I pass previous results nto a function?" I know about series.rolling(), but even during rolling I was not able to get the previous results, only the previous values ​​of the input series.

+4
source share
1 answer

The most special type of operations described is available as cummax, cummin, cumprodand cumsum( f(x) = x + f(x-1)).

expanding : , , , , ..

expanding().apply() . ,

from functools import reduce  # For Python 3.x
ser.expanding().apply(lambda r: reduce(lambda prev, value: prev + 2*value, r))

f(x) = 2x + f(x-1)

, . pandas 1000, expanding().apply() :

np.random.seed(0)    
ser = pd.Series(70 + 5*np.random.randn(10**4))    
ser.tail()
Out: 
9995    60.953592
9996    70.211794
9997    72.584361
9998    69.835397
9999    76.490557
dtype: float64


ser.ewm(alpha=0.1, adjust=False).mean().tail()
Out: 
9995    69.871614
9996    69.905632
9997    70.173505
9998    70.139694
9999    70.774781
dtype: float64

%timeit ser.ewm(alpha=0.1, adjust=False).mean()
1000 loops, best of 3: 779 Β΅s per loop

:

def exp_smoothing(ser, alpha=0.1):
    prev = ser[0]
    res = [prev]
    for cur in ser[1:]:
        prev = alpha*cur + (1-alpha)*prev
        res.append(prev)
    return pd.Series(res, index=ser.index)

exp_smoothing(ser).tail()
Out: 
9995    69.871614
9996    69.905632
9997    70.173505
9998    70.139694
9999    70.774781
dtype: float64

%timeit exp_smoothing(ser)
100 loops, best of 3: 3.54 ms per loop

, expanding().apply():

ser.expanding().apply(lambda r: reduce(lambda p, v: 0.9*p+0.1*v, r)).tail()
Out: 
9995    69.871614
9996    69.905632
9997    70.173505
9998    70.139694
9999    70.774781
dtype: float64

%timeit ser.expanding().apply(lambda r: reduce(lambda p, v: 0.9*p+0.1*v, r))
1 loop, best of 3: 13 s per loop

, cummin, cumsum, x . O(n**2). , , . cumsum cumsum . , , . expanding .

, . DataFrames , , Series. , , , , for , , .

+5

Source: https://habr.com/ru/post/1667443/


All Articles