판다는 보기와 복사본을 생성하기 위해 어떤 규칙을 사용합니까?
데이터 프레임에서 선택한 항목이 원본 데이터 프레임의 복사본인지 또는 원본에 대한 뷰인지 결정할 때 팬더가 사용하는 규칙에 대해 혼란스럽습니다.
예를 들어, 만약 내가 있다면,
df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))
나는 이해합니다.query
복사본을 반환하여 다음과 같은 것.
foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40
원래 데이터 프레임에는 영향을 미치지 않습니다.df
또한 스칼라 또는 명명된 슬라이스가 뷰를 반환하므로 다음과 같은 할당이 가능합니다.
df.iloc[3] = 70
또는
df.ix[1,'B':'E'] = 222
바뀔 것입니다df
하지만 더 복잡한 사건들에 관해서는 저는 갈피를 못 잡니다.예를들면,
df[df.C <= df.B] = 7654321
변화들df
,그렇지만
df[df.C <= df.B].ix[:,'B':'E']
하지 않다.
판다가 사용하는 간단한 규칙이 있나요? 제가 빠진 거죠?이러한 특정 사례에서는 어떤 일이 일어나고 있습니까? 특히, 특정 쿼리를 충족하는 데이터 프레임의 모든 값(또는 값의 하위 집합)을 변경하려면 어떻게 해야 합니까(위의 마지막 예에서 제가 시도한 것처럼)?
참고: 이 질문은 이 질문과 동일하지 않습니다. 설명서를 읽었지만 이 질문을 통해 알게 된 것은 아닙니다.이 주제에 대한 "관련" 질문도 읽었지만 Pandas가 사용하고 있는 간단한 규칙과 특정 쿼리를 충족하는 데이터 프레임의 값(또는 값의 하위 집합)을 수정하는 방법을 아직도 놓치고 있습니다.
규칙은 다음과 같습니다. 이후 오버라이드:
모든 작업은 복사본을 생성합니다.
한다면
inplace=True
제공된 경우 내부 수정됩니다. 일부 작업만 이를 지원합니다.예를 들어, 설정하는 인덱서)입니다.
.loc/.iloc/.iat/.at
제자리에 설치됩니다.단일 d타입 개체에 있는 인덱서는 거의 항상 보기입니다(메모리 레이아웃에 따라 신뢰할 수 없는 이유가 될 수 있음).이것은 주로 효율성을 위한 것입니다.(위의 예는 다음을 위한 것입니다.
.query
이것은 항상 평가된 대로 복사본을 반환합니다.numexpr
)다중 형식 개체에 있는 인덱서는 항상 복사본입니다.
당신의 예는chained indexing
df[df.C <= df.B].loc[:,'B':'E']
작동하는 것이 보장되지 않습니다(따라서 이 작업은 절대 해서는 안 됩니다).
대신 다음을 수행합니다.
df.loc[df.C <= df.B, 'B':'E']
이것이 더 빠르고 항상 작동할 것이기 때문에.
체인화된 인덱싱은 2개의 개별 파이썬 작업이므로 판다가 안정적으로 가로챌 수 없습니다.SettingWithCopyWarning
그러나 그것도 100% 감지할 수 없습니다.)당신이 지적한 개발 문서들은 훨씬 더 자세한 설명을 제공합니다.
판다 1.5.0 이후로 판다는 CoW(Copy-on-Write) 모드를 사용하여 다른 데이터 프레임/시리즈에서 파생된 데이터를 뷰에 복사하는 방식으로 작동합니다.이 옵션을 활성화하면 다른 데이터 프레임/시리즈와 데이터를 공유하는 경우에만 복사본이 생성됩니다.CoW가 비활성화된 경우 슬라이싱과 같은 작업을 수행하면 뷰가 생성되지만(새로운 데이터 프레임이 변경되면 예기치 않게 원본이 변경됨), CoW를 사용하면 복사본이 생성됩니다.
pd.options.mode.copy_on_write = False # disable CoW (this is the default as of pandas 2.0)
df = pd.DataFrame({'A': range(4), 'B': list('abcd')})
df1 = df.iloc[:4] # view
df1.iloc[0] = 100
df.equals(df1) # True <--- df changes together with df1
pd.options.mode.copy_on_write = True # enable CoW (this is planned to be the default by pandas 3.0)
df = pd.DataFrame({'A': range(4), 'B': list('abcd')})
df1 = df.iloc[:4] # copy because data is shared
df1.iloc[0] = 100
df.equals(df1) # False <--- df doesn't change when df1 changes
한 가지 결과는, 판다의 운영이 CoW로 더 빠르다는 것입니다.다음 예제에서는 첫 번째 경우(CoW가 비활성화된 경우) 모든 중간 단계가 복사본을 생성하는 반면, 후자의 경우(CoW가 활성화된 경우)에는 할당 시에만 복사본이 생성됩니다(모든 중간 단계가 보기에 있음).그 때문에 런타임 차이가 있다는 것을 알 수 있습니다(후자의 경우 데이터가 불필요하게 복사되지 않았습니다).
df = pd.DataFrame({'A': range(1_000_000), 'B': range(1_000_000)})
%%timeit
with pd.option_context('mode.copy_on_write', False): # disable CoW in a context manager
df1 = df.add_prefix('col ').set_index('col A').rename_axis('index col').reset_index()
# 30.5 ms ± 561 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
with pd.option_context('mode.copy_on_write', True): # enable CoW in a context manager
df2 = df.add_prefix('col ').set_index('col A').rename_axis('index col').reset_index()
# 18 ms ± 513 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
여기 재미있는 것이 있습니다.
u = df
v = df.loc[:, :]
w = df.iloc[:,:]
z = df.iloc[0:, ]
처음 세 개는 모두 df에 대한 언급인 것 같지만, 마지막 한 개는 그렇지 않습니다!
언급URL : https://stackoverflow.com/questions/23296282/what-rules-does-pandas-use-to-generate-a-view-vs-a-copy
'IT' 카테고리의 다른 글
SQL Server VARBINARY 열에 바이트[]를 삽입하는 방법 (0) | 2023.06.22 |
---|---|
Firebase v3.0.1+에서 로그아웃을 구현하는 가장 좋은 방법은 무엇입니까?업데이트 후 Firebase.unauth가 제거되었습니다. (0) | 2023.06.22 |
T-SQL 표에서 두 번째 행만 선택하는 방법은 무엇입니까? (0) | 2023.06.22 |
Git-Merge --dry-run 옵션이 있습니까? (0) | 2023.06.22 |
특정 경로를 제공하는 http 서버를 어떻게 실행합니까? (0) | 2023.06.22 |