[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.먼저 파생 값을 만듭니다.
먼저 파생 값을 만듭니다.
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.주어진 숫자 열 :
주어진 숫자 열 :
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.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.이 질문이 나온 지 오래되었지만 누군가에게 도움이되기를 바랍니다.
이 질문이 나온 지 오래되었지만 누군가에게 도움이되기를 바랍니다.
면책 조항 :이 솔루션은 표준이 아니지만 잘 작동한다고 생각합니다.
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 배 빠릅니다.
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
'PYTHON' 카테고리의 다른 글
[PYTHON] 팬더가 인식하는 모든 유형은 무엇입니까? (0) | 2018.11.21 |
---|---|
[PYTHON] 클래스를 파이썬에서리스트처럼 동작하도록합니다. (0) | 2018.11.21 |
[PYTHON] 다른 html 페이지에 대한 링크는 어떻게 만듭니 까? (0) | 2018.11.21 |
[PYTHON] Windows의 GeoDjango : "GDAL 라이브러리를 찾을 수 없습니다"/ "OSError : [WinError 126] 지정한 모듈을 찾을 수 없습니다" (0) | 2018.11.21 |
[PYTHON] dict.keys () [0] (Python 3) (0) | 2018.11.20 |