인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

Moonkyung Yang님의 프로필 이미지
Moonkyung Yang

작성한 질문수

공공데이터로 파이썬 데이터 분석 시작하기

[17/20] pandas 의 concat 으로 두 개의 데이터프레임 하나로 합치기

copy()의 목적

작성

·

226

2

df_last_prepare = df_last.loc[df_last["전용면적"] == "전체", cols].copy()

----------------------------------------------------

여기서 copy()를 사용하면 df_last_prepare의 값이 변하더라도, df_last_prepare에 영향을 주지 않는다고 하셨는데, 정확히 그게 무슨의미인지 이해가 잘 가지 않아서요.

혹시 추가 설명 부탁드려도 될까요~? 미리 답변 감사드립니다. 

답변 1

2

박조은님의 프로필 이미지
박조은
지식공유자

안녕하세요.

질문 주신 내용을 어떻게 설명할까 고민하다가 영상으로 만들어 봤습니다.

아래 영상을 참고해 주세요.  => https://youtu.be/Bjsv-ip4Ruk

In [1]:
import pandas as pd
In [2]:
# 데이터프레임에 a 라는 컬럼을 생성합니다.
df = pd.DataFrame({"a": range(5)})
df
Out[2]:
a
0 0
1 1
2 2
3 3
4 4
In [3]:
# 0, 1번 인덱스값만 추출해서 df2 에 사본을 만듭니다.

df2 = df.loc[0:1]
df2
Out[3]:
a
0 0
1 1
In [4]:
# df, df2는 다른 id값을 갖고 있습니다.
print(id(df))
print(id(df2))
140528800964944
140528800922640
In [5]:
df2
Out[5]:
a
0 0
1 1
In [6]:
# df2의 a컬럼의 값을 [4, 5] 로 변경합니다.
# 데이터 프레임의 일부의 사본을 생성해 올 때 copy()를 사용하지 않고 
# 사본을 생성하게 되면 아래와 같은 경고메시지가 발생합니다.
df2["a"] = [4, 5]
df2
/Users//opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:4: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  after removing the cwd from sys.path.
Out[6]:
a
0 4
1 5
In [7]:
# 0 번 인덱스의 a 컬럼에 다른 값을 넣으려고 할때도 아래의 경고 메시지가 출력됩니다.
df2.loc[0, "a"] = 7
df2
/Users//opt/anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:671: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self._setitem_with_indexer(indexer, value)
/Users//opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  
Out[7]:
a
0 7
1 5
In [8]:
# 그리고 df2의 값을 변경해 주었는데 df의 0,1 번 인덱스 값이 변경된 것을 확인할 수 있습니다.
df
Out[8]:
a
0 7
1 5
2 2
3 3
4 4
In [10]:
# 그럼 이번에는 copy()를 통해 df2를 df3에 사본을 생성합니다.
# pandas copy의 기본값은 df.copy(deep: bool = True) 깊은복사 입니다.
df3 = df[:3].copy()
df3
Out[10]:
a
0 7
1 5
2 2
In [11]:
# df, df2, df3는 모두 다른 id값을 가집니다.
print(id(df))
print(id(df2))
print(id(df3))
140528800964944
140528800922640
140528801590800
In [12]:
# df3의 a컬럼의 값을 변경합니다.
df3["a"] = [-2, -3, -4]
df3
Out[12]:
a
0 -2
1 -3
2 -4
In [13]:
# df3의 값을 변경해도 원본 df의 값은 마지막 상태를 유지하고 있습니다.
# df3의 변경값이 df에 반영되지 않았습니다.
df
Out[13]:
a
0 7
1 5
2 2
3 3
4 4
In [ ]:
# .copy()를 통해 깊은 복사를 해주게 되면 사본이 원본을 바라보지 않습니다.
# 따라서 사본을 생성할 때 .copy()를 사용하면 원본값에 영향을 주지 않게 되고 
# 값을 변경할 때도 경고메시지가 출력되지 않습니다.
In [ ]:

Moonkyung Yang님의 프로필 이미지
Moonkyung Yang

작성한 질문수

질문하기