복붙노트

[PYTHON] 이전 값이 적용될 때 dataframe.apply에서 이전 행 값을 사용하는 Pandas의 방법이 있습니까?

PYTHON

이전 값이 적용될 때 dataframe.apply에서 이전 행 값을 사용하는 Pandas의 방법이 있습니까?

다음과 같은 데이터 프레임이 있습니다.

 Index_Date    A    B    C    D
 ===============================
 2015-01-31    10   10   Nan  10
 2015-02-01     2    3   Nan  22 
 2015-02-02    10   60   Nan  280
 2015-02-03    10   100   Nan  250

요구 사항 :

 Index_Date    A    B    C    D
 ===============================
 2015-01-31    10   10   10   10
 2015-02-01     2    3   23   22
 2015-02-02    10   60   290  280
 2015-02-03    10   100  3000 250

C 열은 2015-01-31에 대해 D 값을 취함으로써 유도됩니다.

그런 다음 2015-01-31에 C 값을 사용하고 2015-02-01에 A 값을 곱하여 B를 추가해야합니다.

나는 이것을 적용하여 if else를 사용하여 적용 및 시프트를 시도했으나 키 오류가 발생합니다.

해결법

  1. ==============================

    1.먼저 파생 값을 만듭니다.

    먼저 파생 값을 만듭니다.

    df.loc[0, 'C'] = df.loc[0, 'D']
    

    그런 다음 나머지 행을 반복하고 계산 된 값을 채 웁니다.

    for i in range(1, len(df)):
        df.loc[i, 'C'] = df.loc[i-1, 'C'] * df.loc[i, 'A'] + df.loc[i, 'B']
    
    
      Index_Date   A   B    C    D
    0 2015-01-31  10  10   10   10
    1 2015-02-01   2   3   23   22
    2 2015-02-02  10  60  290  280
    
  2. ==============================

    2.주어진 숫자 열 :

    주어진 숫자 열 :

    lst = []
    cols = ['A']
    for a in range(100, 105):
        lst.append([a])
    df = pd.DataFrame(lst, columns=cols, index=range(5))
    df
    
        A
    0   100
    1   101
    2   102
    3   103
    4   104
    

    shift를 사용하여 이전 행을 참조 할 수 있습니다.

    df['Change'] = df.A - df.A.shift(1)
    df
    
        A   Change
    0   100 NaN
    1   101 1.0
    2   102 1.0
    3   103 1.0
    4   104 1.0
    
  3. ==============================

    3.numpy 배열에 재귀 함수를 적용하는 것이 현재 답변보다 빠릅니다.

    numpy 배열에 재귀 함수를 적용하는 것이 현재 답변보다 빠릅니다.

    df = pd.DataFrame(np.repeat(np.arange(2, 6),3).reshape(4,3), columns=['A', 'B', 'D'])
    new = [df.D.values[0]]
    for i in range(1, len(df.index)):
        new.append(new[i-1]*df.A.values[i]+df.B.values[i])
    df['C'] = new
    

    산출

          A  B  D    C
       0  1  1  1    1
       1  2  2  2    4
       2  3  3  3   15
       3  4  4  4   64
       4  5  5  5  325
    
  4. ==============================

    4.이 질문이 나온 지 오래되었지만 누군가에게 도움이되기를 바랍니다.

    이 질문이 나온 지 오래되었지만 누군가에게 도움이되기를 바랍니다.

    면책 조항 :이 솔루션은 표준이 아니지만 잘 작동한다고 생각합니다.

    import pandas as pd
    import numpy as np
    
    data = np.array([[10, 2, 10, 10],
                     [10, 3, 60, 100],
                     [np.nan] * 4,
                     [10, 22, 280, 250]]).T
    idx = pd.date_range('20150131', end='20150203')
    df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
    df
                   A    B     C    D
     =================================
     2015-01-31    10   10    NaN  10
     2015-02-01    2    3     NaN  22 
     2015-02-02    10   60    NaN  280
     2015-02-03    10   100   NaN  250
    
    def calculate(mul, add):
        global value
        value = value * mul + add
        return value
    
    value = df.loc['2015-01-31', 'D']
    df.loc['2015-01-31', 'C'] = value
    df.loc['2015-02-01':, 'C'] = df.loc['2015-02-01':].apply(lambda row: calculate(*row[['A', 'B']]), axis=1)
    df
                   A    B     C     D
     =================================
     2015-01-31    10   10    10    10
     2015-02-01    2    3     23    22 
     2015-02-02    10   60    290   280
     2015-02-03    10   100   3000  250
    

    그래서 기본적으로 우리는 팬더로부터의 적용과 이전에 계산 된 값을 추적하는 전역 변수의 도움을 사용합니다.

    for 루프와의 시간 비교 :

    data = np.random.random(size=(1000, 4))
    idx = pd.date_range('20150131', end='20171026')
    df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
    df.C = np.nan
    
    df.loc['2015-01-31', 'C'] = df.loc['2015-01-31', 'D']
    
    %%timeit
    for i in df.loc['2015-02-01':].index.date:
        df.loc[i, 'C'] = df.loc[(i - pd.DateOffset(days=1)).date(), 'C'] * df.loc[i, 'A'] + df.loc[i, 'B']
    

    3.2 s 루프 당 ± 114 ms (평균 ± 표준 편차 : 7 회 실행, 각각 1 루프)

    data = np.random.random(size=(1000, 4))
    idx = pd.date_range('20150131', end='20171026')
    df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
    df.C = np.nan
    
    def calculate(mul, add):
        global value
        value = value * mul + add
        return value
    
    value = df.loc['2015-01-31', 'D']
    df.loc['2015-01-31', 'C'] = value
    
    %%timeit
    df.loc['2015-02-01':, 'C'] = df.loc['2015-02-01':].apply(lambda row: calculate(*row[['A', 'B']]), axis=1)
    

    루프 당 1.82 초 ± 64.4ms (평균 ± 표준 편차 7 회, 각 루프 1 회)

    따라서 평균적으로 0.57 배 빠릅니다.

  5. from https://stackoverflow.com/questions/34855859/is-there-a-way-in-pandas-to-use-previous-row-value-in-dataframe-apply-when-previ by cc-by-sa and MIT license