IT

왜 판다의 데이터 프레임을 복사해야 하는가?

itgroup 2023. 1. 31. 20:45
반응형

왜 판다의 데이터 프레임을 복사해야 하는가?

했을 때 을 알 수 ..copy()를 들어, 예,

X = my_dataframe[features_list].copy()

...그냥의

X = my_dataframe[features_list]

데이터 프레임의 복사본을 만드는 이유는 무엇입니까?복사하지 않으면 어떻게 되나요?

이것은 Paul의 대답에 대한 확대이다.Panda에서 DataFrame을 인덱싱하면 초기 DataFrame에 대한 참조가 반환됩니다.따라서 서브셋을 변경하면 초기 데이터 프레임이 변경됩니다.따라서 초기 DataFrame이 변경되지 않도록 하려면 복사본을 사용해야 합니다.다음 코드를 고려합니다.

df = DataFrame({'x': [1,2]})
df_sub = df[0:1]
df_sub.x = -1
print(df)

다음과 같은 이점을 얻을 수 있습니다.

   x
0 -1
1  2

반면 다음 항목은 변경되지 않습니다.

df_sub_copy = df[0:1].copy()
df_sub_copy.x = -1

이 대답은 판다의 새로운 버전에서는 더 이상 사용되지 않는다.문서 참조

복사본을 만들지 않으면 dataFrame을 다른 이름으로 할당하더라도 인덱스는 다른 곳에서 조작될 수 있기 때문입니다.

예를 들어 다음과 같습니다.

df2 = df
func1(df2)
func2(df)

func1은 df2를 변경하여 df를 변경할 수 있으므로 이를 회피할 수 있습니다.

df2 = df.copy()
func1(df2)
func2(df)

복사 또는 보기를 반환하는 것은 인덱싱의 종류에 따라 다르다는 점을 언급해야 합니다.

팬더 문서에는 다음과 같이 기재되어 있습니다.

보기와 복사본 반환

데이터에 대한 보기가 반환되는 시점에 대한 규칙은 전적으로 NumPy에 따라 달라집니다.색인화 작업에 라벨 배열 또는 부울 벡터가 관여할 때마다 결과는 복사본이 됩니다.단일 라벨/스칼라 인덱싱 및 슬라이싱(예: df.ix[3:6] 또는 df)ix[:, 'A', 뷰가 반환됩니다.

하고 '연쇄 인덱싱'을하는 것입니다.SettingWithCopyWarning.

연쇄 .dfc['A'][0] = 111

문서에서는 보기 반환복사본 반환에서 연쇄 인덱싱을 피해야 한다고 합니다.다음으로 그 문서에서 약간 변경된 예를 제시하겠습니다.

In [1]: import pandas as pd

In [2]: dfc = pd.DataFrame({'A':['aaa','bbb','ccc'],'B':[1,2,3]})

In [3]: dfc
Out[3]:
    A   B
0   aaa 1
1   bbb 2
2   ccc 3

In [4]: aColumn = dfc['A']

In [5]: aColumn[0] = 111
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

In [6]: dfc
Out[6]:
    A   B
0   111 1
1   bbb 2
2   ccc 3

★★★★★★★★★★★★★★★★★★.aColumn에 DataFrame을 합니다.aColumn인 이 되다dfc, 행에 요.다음으로 행의 인덱스를 먼저 작성하면 다음과 같습니다.

In [7]: zero_row = dfc.loc[0]

In [8]: zero_row['A'] = 222
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

In [9]: dfc
Out[9]:
    A   B
0   111 1
1   bbb 2
2   ccc 3

에는 ★★★★★★★★★★★★★★★★★.zero_row카피이기 에, 오리지날 「」는 카피입니다.dfc을 사용하다

위의 두 가지 예에서 원본 DataFrame을 변경할지 여부가 모호하다는 것을 알 수 있습니다.이것은 다음과 같은 내용을 쓰는 경우 특히 위험합니다.

In [10]: dfc.loc[0]['A'] = 333
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

In [11]: dfc
Out[11]:
    A   B
0   111 1
1   bbb 2
2   ccc 3

이번에는 전혀 효과가 없었다., 그럼 에는 바꿔보겠습니다.dfcdfc.loc[0]이치노이다, 중간값이다, 이런 것은 .dfc.loc[0] ★★★★★★★★★★★★★★★★★」dfc['A']보기 또는 복사본이므로 원본 DataFrame이 업데이트될지 여부는 보장되지 않습니다.그래서 연쇄 인덱싱을 피해야 하고, 판다는 그 유전자를 만들어냅니다.SettingWithCopyWarning이런 종류의 연쇄 색인 업데이트에 사용할 수 있습니다.

지금은 의 사용법입니다..copy()경고를 없애려면 복사본을 작성하여 의사를 명시합니다.

In [12]: zero_row_copy = dfc.loc[0].copy()

In [13]: zero_row_copy['A'] = 444 # This time no warning

에, 의 카피를 알 수 .dfc절대 변하지 않을 것이며, 당신은 그것이 바뀔 것이라고 예상하지 않을 것이다.과 일치하고, 그 에 신의음음음음, 음음음음음음음 your your your.SettingWithCopyWarning라집니니다다

원래 Data 하는 경우 Frame을 .loc:

In [14]: dfc.loc[0,'A'] = 555

In [15]: dfc
Out[15]:
    A   B
0   555 1
1   bbb 2
2   ccc 3

다음과 같은 데이터 프레임이 있다고 가정합니다.

df1
     A    B    C    D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0

것을 때df2와 같다df1 를 사용하지 않습니다.copy

df2=df1
df2
     A    B    C    D
4 -1.0 -1.0 -1.0 -1.0
5 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0
6 -1.0 -1.0 -1.0 -1.0

그리고 df2 값만 아래와 같이 수정하고 싶습니다.

df2.iloc[0,0]='changed'

df2
         A    B    C    D
4  changed -1.0 -1.0 -1.0
5       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0

동시에 df1도 변경됩니다.

df1
         A    B    C    D
4  changed -1.0 -1.0 -1.0
5       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0

2'df이므로object 이렇게 '을 할 수 있습니다.id

id(df1)
140367679979600
id(df2)
140367679979600

즉, 동일한 개체로 변경되고 다른 개체로 변경되면 동일한 값도 마찬가지입니다.


「 」를 copy이에서, 「」는 「」입니다」df1 ★★★★★★★★★★★★★★★★★」df2 것으로 object둘 중 하나에 동일한 변경을 가해도 다른 하나는 변경되지 않습니다.

df2=df1.copy()
id(df1)
140367679979600
id(df2)
140367674641232

df1.iloc[0,0]='changedback'
df2
         A    B    C    D
4  changed -1.0 -1.0 -1.0
5       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0
6       -1 -1.0 -1.0 -1.0

원래 프레임의 을 할 는, 하는 것이 합니다.SettingWithCopyWarning

일반적으로 원본 데이터 프레임에서 작업하는 것이 원본 데이터 프레임에서 작업하는 것보다 더 안전합니다. 단, 원본 데이터 프레임이 더 이상 필요하지 않고 조작된 버전을 사용하려는 경우에는 예외입니다.통상, 조작한 버전 등과 비교하기 위해서, 원래의 데이터 프레임은 어느 정도 사용할 수 있습니다.따라서 대부분의 사람들은 복사 작업을 하고 마지막에 병합합니다.

Panda Deep copy는 초기 Data Frame을 변경하지 않습니다.

이 기능은 특히 Data Frame을 정규화하고 초기 df를 변경하지 않는 경우에 유용합니다.예:

df = pd.DataFrame(np.arange(20).reshape(2,10))

그런 다음 데이터를 정규화합니다.

# Using Sklearn MinMaxSacaler method
scaler = preprocessing.MinMaxScaler()

첫 번째 df를 기반으로 새 df를 만들고 첫 번째 df를 변경하지 않으려면 .copy() 메서드를 사용해야 합니다.

new_df = pd.DataFrame(df).copy() # Deep Copy
for i in range(10):
    pd_features[i] = scaler.fit_transform(unnormal_pd_features[i].values.reshape(-1,1))

그렇지 않으면 원래 df도 바뀔 거야

copy()를 사용하지 않고 아래의 코드 행을 사용할 때까지 copy()를 사용하는 것이 너무 부주의했습니다.df_genel3의 변경은 df_genel에 영향을 줍니다.

df_genel3 = df_genel
df_genel3.loc[(df_genel3['Hareket']=='İmha') , 'Hareket_Tutar'] = tutar 

copy()는 문제를 해결했습니다.

df_genel3 = df_genel.copy()
df_genel3.loc[(df_genel3['Hareket']=='İmha') , 'Hareket_Tutar'] = tutar

언급URL : https://stackoverflow.com/questions/27673231/why-should-i-make-a-copy-of-a-data-frame-in-pandas

반응형