2017-02-09 2 views
0

행을 반복 할 때 일부 열 값을 업데이트하고 싶지만 오랜 시간이 걸립니다. 제안 된 herehere과 같이 대신 itertuples()을 사용하고, 하나의 반복에서 두 개의 열을 업데이트하고자하므로 apply 함수를 사용할 수 없습니다.Python Pandas : 행을 반복하면서 DataFrame 값을 업데이트하는 중

아래 예제 코드와 관련없는 10-ish 이상의 열이 포함되어 있으므로 간단한 예제를 사용합니다. 여기에 그들을 포함 시키면 코드가 더 나빠질 것입니다.

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randint(0, 5, size=(90000, 4)), 
        columns=['Initial', 'A', 'B']) 

df['code'] = list('KLMNOP' * 15000) # Adding column 'code' 

df = df.sort_values('code') # Sorting the df by 'code' 

df['Total'] = np.nan 

다음, 나는 AB의 값을 기준으로 열 InitialTotal을 업데이트하려는 다음도 이전 행의 Total하여 Initial를 업데이트. 내가 Total 현재 code는 이전 행의 code

코드는 거의 한 시간 동안 실행
def produce_total(init, a, b): 
    if a >= 2 and b >= 2: 
     return init + 1 
    return init 

last_code = '' 
last_total = -100 
for row in df.itertuples(): 
    # Print the current checkpoint 
    if(row.Index % 1000 == 0): 
     print row.Index 

    # Carry over the prev Total to current Initial 
    if last_code == row.code: 
     df.loc[row.Index, 'Initial'] = last_total 

    # Prepare the updated Initial value 
    # Because what is inside 'row' seems unaffected by the update 
    new_initial = df.loc[row.Index, 'Initial'] 

    # Find Total and assign to the df 
    new_total = produce_total(
     new_initial, 
     row.A, 
     row.B 
    ) 
    df.loc[row.Index, 'Total'] = new_total 

    last_code = row.code 
    last_total = new_total 

같은 경우 다음 행의 Initial 이월,하지만 지수 30000 틱에 도달하고, 의미한다. 이 작업을 수행하는 또 다른 또는 두 가지 효율적인 방법에 대한 아이디어 또는 제안?

또는 고려해야 할 다른 측면이 있습니다 (일부 열 제거 등)?

고맙습니다.

답변

0

IIUC, 당신이 내가 처음 총하는 & B의 값이 2보다 큰 경우 지금까지 항상 & -100에 하나를 추가 할 각 코드, 가정 무엇 pandas cumsum

사용할 필요가 이전 행 총계.

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randint(0, 5, size=(90000, 3)), 
        columns=['Initial', 'A', 'B']) 
df['code'] = list('KLMNOP' * 15000) # Adding column 'code' 

df = df.sort_values('code') # Sorting the df by 'code' 

df['new_Initial'] = np.where((df.A>2) & (df.B>2) ,1,0) 

df.set_value(0, 'new_Initial', -100) 
df.set_value(1, 'new_Initial', -100) 
df.set_value(2, 'new_Initial', -100) 
df.set_value(3, 'new_Initial', -100) 
df.set_value(4, 'new_Initial', -100) 

df['Total'] = df.groupby(['code']).new_Initial.cumsum() 
print df 

출력

 Initial A B code new_Initial Total 
0   1 0 2 K   -100 -100 
84312  4 1 2 K   0 -100 
34110  1 4 0 K   0 -100 
34104  2 0 4 K   0 -100 
34098  0 4 3 K   1 -99 
34092  4 1 0 K   0 -99 
34086  2 2 4 K   0 -99 
34080  1 2 2 K   0 -99 
84318  4 2 2 K   0 -99 
34074  2 3 2 K   0 -99 
34116  2 1 1 K   0 -99 
34068  4 3 0 K   0 -99 
34056  4 3 4 K   1 -98 
34050  2 4 1 K   0 -98 
34044  1 1 0 K   0 -98 
84324  1 0 2 K   0 -98 
34038  0 1 0 K   0 -98 
34032  1 2 0 K   0 -98 
34026  0 1 1 K   0 -98 
34020  0 4 4 K   1 -97 
34014  0 0 4 K   0 -97 
34062  4 0 3 K   0 -97 
34122  2 3 3 K   1 -96 
34128  1 1 1 K   0 -96 
34134  3 2 3 K   0 -96 
34242  0 1 3 K   0 -96 
34236  4 3 2 K   0 -96 
34230  4 3 1 K   0 -96 
34224  4 2 0 K   0 -96 
84294  2 3 2 K   0 -96 
     ... .. .. ...   ... ... 
51245  4 4 0 P   0 2355 
51239  3 3 1 P   0 2355 
51365  0 1 2 P   0 2355 
51371  1 3 4 P   1 2356 
51377  4 2 3 P   0 2356 
51383  0 2 2 P   0 2356 
51515  0 2 1 P   0 2356 
51509  4 2 2 P   0 2356 
51503  3 0 0 P   0 2356 
51497  1 3 0 P   0 2356 
51491  4 3 2 P   0 2356 
51485  3 3 2 P   0 2356 
51479  4 0 3 P   0 2356 
51473  2 3 3 P   1 2357 
51467  3 4 3 P   1 2358 
51461  4 0 2 P   0 2358 
51827  4 0 2 P   0 2358 
51455  1 2 1 P   0 2358 
51443  3 0 4 P   0 2358 
51437  0 0 4 P   0 2358 
51431  2 2 2 P   0 2358 
51425  3 2 1 P   0 2358 
51419  2 3 2 P   0 2358 
51413  2 0 2 P   0 2358 
51407  0 1 3 P   0 2358 
51401  4 2 2 P   0 2358 
51395  2 4 4 P   1 2359 
51389  1 3 3 P   1 2360 
51449  3 4 0 P   0 2360 
89999  0 1 4 P   0 2360 
관련 문제