복붙노트

[PYTHON] Pandas : dropna 이후 inplace rename을위한 특별한 성능 저하

PYTHON

Pandas : dropna 이후 inplace rename을위한 특별한 성능 저하

나는 이것을 판다 문제에 관한 문제로보고했다. 다른 한편으로는 비슷한 문제가 발생할 경우에 대비하여 다른 사람들을 구하기 위해 여기에 게시합니다.

최적화되어야 할 프로세스를 프로파일 링 할 때, 열 이름을 변경하지 않으면 성능 (실행 시간)이 x120만큼 향상된다는 것을 알게되었습니다. 프로파일 링은 이것이 가비지 콜렉션과 관련됨을 나타냅니다 (아래 참조).

또한 dropna 방식을 피함으로써 예상되는 성능을 회복합니다.

다음은 x12 요소의 간단한 예입니다.

import pandas as pd
import numpy as np
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)

%% prun의 첫 번째 출력 행 :

%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})

예상되는 성능은 dropna 방법을 피함으로써 복구됩니다.

%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
#no dropna:
df = (df1-df2)#.dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
## no dropna
df = (df1-df2)#.dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})

해결법

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

    1.이것은 github에 대한 설명의 사본입니다.

    이것은 github에 대한 설명의 사본입니다.

    내부 운영이 실제로 더 빠르다고 보장 할 수는 없습니다. 종종 실제로 사본과 동일한 작업이지만 최상위 레벨 참조가 재 할당됩니다.

    이 경우 성능 차이의 원인은 다음과 같습니다.

    (df1-df2) .dropna () 호출은 데이터 프레임의 조각을 만듭니다. 새로운 작업을 적용 할 때 복사본이 될 수 있기 때문에 SettingWithCopy 검사를 트리거합니다 (그러나 종종 그렇지 않음).

    이 검사는 일부 캐시 참조를 제거하여 사본인지 확인하기 위해 가비지 수집을 수행해야합니다. 불행히도 파이썬 구문은 이것을 피할 수 없게 만듭니다.

    단순히 사본을 먼저 작성하면 이런 일이 발생할 수 없습니다.

    df = (df1-df2).dropna().copy()
    

    inplace 운영이 뒤 따르는 것은 이전만큼 성과가있을 것입니다.

    개인적인 의견 : 제자리에서의 작업은 절대로 사용하지 않습니다. 이 구문은 읽기가 어렵고 이점이 없습니다.

  2. from https://stackoverflow.com/questions/22532302/pandas-peculiar-performance-drop-for-inplace-rename-after-dropna by cc-by-sa and MIT license