পান্ডসে আমি কেন ডেটা ফ্রেমের একটি অনুলিপি তৈরি করব


183

প্যারেন্ট ডেটাফ্রেম থেকে উপ ডেটা ফ্রেম নির্বাচন করার সময়, আমি লক্ষ্য করেছি যে কিছু প্রোগ্রামার .copy()পদ্ধতিটি ব্যবহার করে ডেটা ফ্রেমের একটি অনুলিপি তৈরি করে ।

তারা কেন ডেটা ফ্রেমের একটি অনুলিপি তৈরি করছে? আমি যদি একটি অনুলিপি না তৈরি করি তবে কী হবে?


6
আমার ধারণা তারা উত্স ডেটা ফ্রেমটি সংশোধন না করার জন্য অতিরিক্ত সতর্কতা নিচ্ছে। সম্ভবত অপ্রয়োজনীয়, তবে আপনি যখন ইন্টারেক্টিভভাবে কোনও কিছু নিক্ষেপ করছেন তখন দুঃখের চেয়ে ভাল।
পল এইচ

8
আমি ধরে নিয়েছি এটি নেতিবাচক দেওয়ার জন্য একটি বোকা প্রশ্ন নয়।
এলিজাবেথ সুসান জোসেফ

উত্তর:


202

এটি পৌলের উত্তরে প্রসারিত হয়। পান্ডাসে, ডেটাফ্রেমকে সূচীকরণ প্রাথমিক ডেটা ফ্রেমের একটি রেফারেন্স দেয়। সুতরাং, সাবসেট পরিবর্তন করা প্রাথমিক ডেটা ফ্রেম পরিবর্তন করবে। সুতরাং, আপনি যদি প্রাথমিক ডেটা ফ্রেমটি পরিবর্তন না হয় তা নিশ্চিত করতে চান তবে আপনি অনুলিপিটি ব্যবহার করতে চান। নিম্নলিখিত কোড বিবেচনা করুন:

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

তুমি পাবে:

x
0 -1
1  2

বিপরীতে, নিম্নলিখিত পাতা df অপরিবর্তিত:

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

6
এটি কি একটি গভীর অনুলিপি?
বিকাশগ

6
হ্যাঁ. ডিফল্ট মোডটি "গভীর" কপি! pandas.pydata.org/pandas-docs/stable/reference/api/...
Ambareesh

44

কারণ আপনি যদি অনুলিপি না তৈরি করেন তবে সূচিগুলি অন্য কোনও জায়গায় ডেটা ফ্রেম নির্ধারণ করা সত্ত্বেও সূচিগুলি অন্য কোথাও ম্যানিপুলেটেড হতে পারে।

উদাহরণ স্বরূপ:

df2 = df
func1(df2)
func2(df)

func1 df2 সংশোধন করে df সংশোধন করতে পারে, যাতে তা এড়াতে:

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

অপেক্ষা করুন অপেক্ষা করুন, আপনি কেন ব্যাখ্যা করতে পারেন কেন এটি ঘটে? কোন মানে নেই।
NoName

2
এটি কারণ প্রথম উদাহরণে, `df2 = df , both variables reference the same DataFrame instance. So any changes made to df` বা df2একই বস্তুর উদাহরণে তৈরি করা হবে। যেখানে মধ্যে df2 = df.copy()একটি দ্বিতীয় বস্তুর উদাহরণস্বরূপ তৈরি করা হয়, প্রথম এক একটি কপি, কিন্তু এখন dfdf2বিভিন্ন বস্তুর দৃষ্টান্ত এবং কোনো প্রকার পরিবর্তন রেফারেন্স তাদের নিজ নিজ DataFrame ক্ষেত্রটিকেই তৈরি করা হবে।
পেড্রো

17

এটি উল্লেখ করা প্রয়োজন যে ফিরতি অনুলিপি বা ভিউ নির্ভরশীলতার উপর নির্ভর করে।

পান্ডাস ডকুমেন্টেশন বলে:

একটি অনুলিপি বনাম একটি দর্শন ফেরত

কখন ডেটাতে কোনও ভিউ ফিরে আসে সে সম্পর্কে নিয়মগুলি পুরোপুরি NumPy এর উপর নির্ভর করে। যখনই কোনও লেবেল বা বুলিয়ান ভেক্টর সূচীকরণের ক্রিয়াকলাপে জড়িত তখন ফলাফলটি অনুলিপি হবে। একক লেবেল / স্কেলার সূচক এবং স্লাইসিং সহ, উদাহরণস্বরূপ df.ix [3: 6] বা df.ix [:, 'এ'] দিয়ে একটি দৃশ্য ফিরে আসবে।



12

প্রাথমিক উদ্দেশ্য হল শৃঙ্খলিত সূচী এড়ানো এবং এটিকে নির্মূল করা 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পরিবর্তন করা হয়নি।

উপরের এই দুটি উদাহরণ থেকে আমরা দেখতে পাচ্ছি যে আপনি মূল ডেটাফ্রেম পরিবর্তন করতে চান কিনা তা অস্পষ্ট। আপনি নিম্নলিখিত হিসাবে কিছু লিখলে এটি বিশেষত বিপজ্জনক:

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

এবার মোটেই কাজ হয়নি। এখানে আমরা পরিবর্তন করতে চেয়েছিলাম dfc, কিন্তু আমরা আসলে একটি অন্তর্বর্তী মানটি সংশোধন করেছিলাম dfc.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কখনই পরিবর্তিত হবে না এবং আপনি এটি পরিবর্তন করারও আশা করছেন না। আপনার প্রত্যাশা আচরণের সাথে মেলে, তবে SettingWithCopyWarningঅদৃশ্য হয়ে যায়।

দ্রষ্টব্য, আপনি যদি মূল ডেটা ফ্রেমটি সংশোধন করতে চান তবে দস্তাবেজটি আপনাকে ব্যবহার করার পরামর্শ দেয় loc:

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

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

2

সাধারণভাবে আসল ডেটা ফ্রেমের তুলনায় অনুলিপিগুলিতে কাজ করা আরও নিরাপদ, আপনি যখন জানবেন যে আপনাকে আর আসলটির প্রয়োজন হবে না এবং ম্যানিপুলেটেড সংস্করণ দিয়ে এগিয়ে যেতে চান। সাধারণভাবে, ম্যানিপুলেটেড সংস্করণ ইত্যাদির সাথে তুলনা করার জন্য আপনার কাছে এখনও মূল ডেটা ফ্রেমের কিছু ব্যবহার থাকবে। সুতরাং, বেশিরভাগ লোক অনুলিপিগুলিতে কাজ করে এবং শেষে মার্জ করে।


0

ধরে নেওয়া হয়েছে আপনার নীচের মতো ডেটা ফ্রেম রয়েছে

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

একই সাথে ডিএফ 1 পাশাপাশি পরিবর্তন করা হয়

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

যেহেতু দুটি ডিএফ একই 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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.