Memahami di tempat = Benar


109

Di pandasperpustakaan berkali-kali ada opsi untuk mengubah objek di tempat seperti dengan pernyataan berikut ...

df.dropna(axis='index', how='all', inplace=True)

Saya ingin tahu apa yang dikembalikan serta bagaimana objek ditangani ketika inplace=Truedilewatkan vs kapan inplace=False.

Apakah semua operasi berubah selfkapan inplace=True? Dan kapan inplace=Falseobjek baru dibuat segera seperti new_df = selfdan kemudian new_dfdikembalikan?


14
Ya, inplace=Truemengembalikan None inplace=Falsesalinan objek dengan operasi yang dilakukan. Dokumennya cukup jelas tentang ini, apakah ada yang membingungkan dengan bagian tertentu? SpeficallyIf True, do operation inplace and return None.
EdChum

Saya membuat subclass objek DataFrame dan dengan operasi seperti penggabungan tampaknya tidak mungkin untuk melakukannya di tempat ... self = self.merge(new_df, how='left', on='column2' Saya tidak yakin apakah mungkin untuk menetapkan ulang sendiri
Aran Freel

1
Anda benar bahwa DataFrame.merge tidak memiliki inplaceargumen. Ini mengembalikan DataFrame, jadi tidak ada masalah penugasan ulang.
JAV

Bisakah seseorang juga menyoroti keuntungan menggunakannya dalam hal konsumsi sumber daya?
markroxor

2
@markroxor Sebenarnya tidak banyak. Dalam beberapa kasus, inplacetindakan bisa menjadi sedikit lebih cepat karena Anda tidak benar-benar harus mengembalikan salinan hasilnya. Tapi itu saja. Ada lebih banyak alasan untuk tidak menggunakannya.
cs95

Jawaban:


99

Ketika inplace=Truediteruskan, data diganti namanya di tempatnya (tidak mengembalikan apa-apa), jadi Anda akan menggunakan:

df.an_operation(inplace=True)

Ketika inplace=Falsediteruskan (ini adalah nilai default, jadi tidak perlu), melakukan operasi dan mengembalikan salinan objek, jadi Anda akan menggunakan:

df = df.an_operation(inplace=False) 

Apakah saya benar dalam berpikir bahwa inplaceitu hanya pilihan untuk metode yang mengubah data yang ada, tetapi tidak untuk metode yang 'membentuk kembali' data. Misalnya, saya bisa .set_index (inplace = True) karena ini menerapkan nilai ke indeks yang ada, tetapi tidak bisa .reindex (inplace = True) karena ini bisa membuat baris tambahan pada DataFrame yang tidak ada di array sebelumnya ?
ac24

4
Metode ini .dropna()menerima inplace=Truedan pasti dapat membentuk kembali kerangka data, jadi tidak.
jorijnsmit

3
Anda harus berhati-hati di sini. @ ac24 sebenarnya kurang lebih benar. Saat dropnamengembalikan kerangka data dengan bentuk berbeda, itu tidak benar-benar membentuk kembali data yang mendasarinya - itu hanya mengembalikan topeng di atasnya (bila inplace=False), yang dapat menyebabkan yang ditakuti SettingWithCopyWarning. Hanya jika tidak ada lagi referensi ke larik nilai lama, panda akan terbentuk kembali sesuai dengan topengnya. Aturan praktis yang lebih baik adalah: inplacetersedia saat operasi tidak memerlukan pengalokasian backing ndarray nilai baru.
BallpointBen

49

Di panda, apakah inplace = True dianggap berbahaya, atau tidak?

TLDR; Ya, benar.

  • inplace, bertentangan dengan namanya, seringkali tidak menghalangi pembuatan salinan, dan (hampir) tidak pernah menawarkan manfaat kinerja apa pun
  • inplace tidak berfungsi dengan rangkaian metode
  • inplace adalah masalah umum bagi pemula, jadi menghapus opsi ini akan menyederhanakan API

Saya tidak menyarankan pengaturan parameter ini karena fungsinya kecil . Lihat masalah GitHub ini yang mengusulkan agar inplaceargumen tidak digunakan lagi di seluruh api.

Ini adalah kesalahpahaman umum bahwa penggunaan inplace=Trueakan menghasilkan kode yang lebih efisien atau dioptimalkan. Pada kenyataannya, sama sekali tidak ada manfaat kinerja untuk digunakan inplace=True. Baik di tempat dan out-of-tempat versi membuat salinan data pula , dengan versi di tempat otomatis menempatkan copy kembali.

inplace=Trueadalah kesalahan umum bagi pemula. Misalnya, ini dapat memicuSettingWithCopyWarning :

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

Memanggil fungsi pada kolom DataFrame dengan inplace=True mungkin atau mungkin tidak berfungsi . Ini terutama benar ketika pengindeksan berantai terlibat.

Seakan masalah yang dijelaskan di atas tidak cukup, inplace=Truejuga menghalangi perangkaian metode . Bandingkan cara kerja

result = df.some_function1().reset_index().some_function2()

Sebagai lawan

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

Yang pertama cocok untuk organisasi kode dan keterbacaan yang lebih baik.


Klaim pendukung lainnya adalah bahwa API untuk set_axisbaru-baru ini diubah sedemikian rupa sehingga inplacenilai default dialihkan dari True ke False. Lihat GH27600 . Kerja bagus, devs!


1
Tentu inplace=Truetidak berfungsi dengan rantai dll. Tapi yang jelas adalah Anda memahami apa yang dilakukannya secara konseptual. Secara pribadi saya merasa sedikit lebih bersih untuk menghindari penugasan- Apakah Anda juga ingin menghapus list.sortdll dari perpustakaan standar?
Chris_Rands

4
Saya tidak berpikir itu perbandingan yang adil. Ada beberapa manfaat yang jelas menggunakan list.sort versus sort. Sama halnya dengan fungsi tempat lainnya. Tidak ada manfaat nyata di sini, perangkaian metode jauh lebih umum di panda dan ada rencana untuk penghentian argumen ini.
cs95

Saya juga merasa sedikit lebih bersih untuk menghindari tugas: juga, misalnya, python list.append()juga ada di tempat, sementara pandas df.append tidak (dan bahkan tidak mendukung di tempat), yang membuat saya kesal tanpa akhir. Itulah sebabnya saya ingin tahu, hanya untuk memahami apa manfaat sebenarnya - apa manfaat nyata menggunakan list.sort versus sortir, selain menghindari penugasan? Jika tidak, menurut saya ada manfaat nyata di sini - saya dapat menghindari tugas, yang menurut saya pribadi lebih mudah dibaca.
sdbbs

1
@sdbbs list.append()menambahkan ke daftar yang ada. df.appendmembuat salinan data Anda (tidak masalah apakah Anda memiliki 5 baris atau 5 juta), lalu menambahkan baris baru ke salinan Anda, lalu mengembalikannya. Menurut Anda apa yang lebih masuk akal? Sedangkan untuk df.append, HINDARI SEBANYAK MUNGKIN . Menurut saya ini bukan contoh yang baik untuk memperdebatkan inplace = True, saya bahkan tidak berpikir bahwa fungsi tersebut memiliki tempat di API.
cs95

46

Cara saya menggunakannya

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

Atau

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

KESIMPULAN:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign

5
Hai @Nabin, Itu terlalu jelas bagi siapa pun yang mengerjakan Pandas dan Numpy :-)
Vetrivel PS

6

The inplaceparameter:

df.dropna(axis='index', how='all', inplace=True)

secara Pandasumum dan berarti:

1. Panda membuat salinan dari data asli

2. ... melakukan beberapa perhitungan di atasnya

3. ... memberikan hasil ke data asli.

4. ... menghapus salinan.

Seperti yang dapat Anda baca di sisa jawaban saya adalah lebih lanjut di bawah, kita masih bisa memiliki alasan yang baik untuk menggunakan parameter ini yaitu inplace operations, tapi kita harus menghindari jika kita bisa, karena menghasilkan masalah yang lebih, seperti:

1. Kode Anda akan lebih sulit untuk di-debug (Sebenarnya SettingwithCopyWarning berarti memperingatkan Anda tentang kemungkinan masalah ini)

2. Konflik dengan rangkaian metode


Jadi adakah kasus ketika kita harus menggunakannya?

Pasti ya. Jika kita menggunakan panda atau alat apa pun untuk menangani kumpulan data yang sangat besar, kita dapat dengan mudah menghadapi situasi, di mana beberapa data besar dapat menghabiskan seluruh memori kita. Untuk menghindari efek yang tidak diinginkan ini kita dapat menggunakan beberapa teknik seperti perangkaian metode :

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

yang membuat kode kita lebih ringkas (meskipun lebih sulit untuk ditafsirkan dan di-debug juga) dan menggunakan lebih sedikit memori karena metode yang dirantai berfungsi dengan nilai yang dikembalikan metode lain, sehingga hanya menghasilkan satu salinan data masukan. Kita dapat melihat dengan jelas, bahwa kita akan memiliki 2 x konsumsi memori data asli setelah operasi ini.

Atau kita dapat menggunakan inplaceparameter (meskipun lebih sulit untuk menafsirkan dan men-debug juga) konsumsi memori kita akan menjadi 2 x data asli , tetapi konsumsi memori kita setelah operasi ini tetap 1 x data asli , yang jika seseorang bekerja dengan dataset besar tahu persis bisa menjadi a manfaat besar.


Kesimpulan akhir:

Hindari menggunakan inplaceparameter kecuali jika Anda tidak bekerja dengan data besar dan waspadai kemungkinan masalahnya jika masih menggunakannya.


2

Simpan ke variabel yang sama

data["column01"].where(data["column01"]< 5, inplace=True)

Simpan ke variabel terpisah

data["column02"] = data["column01"].where(data["column1"]< 5)

Namun, Anda selalu dapat menimpa variabel tersebut

data["column01"] = data["column01"].where(data["column1"]< 5)

FYI: Secara default inplace = False


1

Saat mencoba membuat perubahan pada bingkai data Pandas menggunakan sebuah fungsi, kami menggunakan 'inplace = True' jika kami ingin melakukan perubahan pada kerangka data. Oleh karena itu, baris pertama dalam kode berikut mengubah nama kolom pertama di 'df' menjadi 'Nilai'. Kita perlu memanggil database jika ingin melihat database yang dihasilkan.

df.rename(columns={0: 'Grades'}, inplace=True)
df

Kami menggunakan 'inplace = False' (ini juga merupakan nilai default) ketika kami tidak ingin melakukan perubahan tetapi hanya mencetak database yang dihasilkan. Jadi, pada dasarnya salinan dari database asli dengan perubahan yang dilakukan dicetak tanpa mengubah database asli.

Agar lebih jelas, kode-kode berikut melakukan hal yang sama:

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}

0

inplace=True digunakan tergantung apakah Anda ingin membuat perubahan ke df asli atau tidak.

df.drop_duplicates()

hanya akan membuat tampilan dari nilai yang dijatuhkan tetapi tidak membuat perubahan apa pun pada df

df.drop_duplicates(inplace  = True)

akan menjatuhkan nilai dan membuat perubahan pada df.

Semoga ini membantu.:)


0

inplace=Truemembuat fungsinya tidak murni. Ini mengubah kerangka data asli dan mengembalikan Tidak Ada. Dalam hal ini, Anda memutuskan rantai DSL. Karena sebagian besar fungsi bingkai data mengembalikan kerangka data baru, Anda dapat menggunakan DSL dengan nyaman. Suka

df.sort_values().rename().to_csv()

Panggilan fungsi dengan inplace=Truepengembalian Tidak ada dan rantai DSL terputus. Sebagai contoh

df.sort_values(inplace=True).rename().to_csv()

akan melempar NoneType object has no attribute 'rename'

Sesuatu yang mirip dengan build-in sort dan sortir python. lst.sort()mengembalikan Nonedan sorted(lst)mengembalikan daftar baru.

Umumnya, jangan gunakan inplace=Truekecuali Anda memiliki alasan khusus untuk melakukannya. Ketika Anda harus menulis kode penugasan ulang seperti df = df.sort_values(), coba lampirkan panggilan fungsi di rantai DSL, misalnya

df = pd.read_csv().sort_values()...

menyediakan kode kerja yang tepat dengan format yang tepat akan sangat membantu pengguna untuk memahami jawaban Anda lebih cepat. Meminta Anda melakukan hal yang sama. Saya bukan ahli panda, jadi tidak dapat memformat ulang jawaban Anda, tetapi sangat disarankan,
Anand Vaidya

0

Sejauh pengalaman saya di panda, saya ingin menjawab.

Argumen 'inplace = True' berarti bingkai data harus membuat perubahan permanen misalnya.

    df.dropna(axis='index', how='all', inplace=True)

mengubah kerangka data yang sama (karena panda ini menemukan entri NaN dalam indeks dan melepaskannya). Jika kita mencoba

    df.dropna(axis='index', how='all')

pandas menunjukkan kerangka data dengan perubahan yang kami buat tetapi tidak akan mengubah kerangka data asli 'df'.


0

Jika Anda tidak menggunakan inplace = True atau Anda menggunakan inplace = False, pada dasarnya Anda mendapatkan salinannya.

Jadi misalnya:

testdf.sort_values(inplace=True, by='volume', ascending=False)

akan mengubah struktur dengan data yang diurutkan dalam urutan menurun.

kemudian:

testdf2 = testdf.sort_values( by='volume', ascending=True)

akan membuat testdf2 menjadi salinan. nilainya akan sama tetapi jenisnya akan dibalik dan Anda akan memiliki objek independen.

lalu diberi kolom lain, ucapkan LongMA dan Anda melakukannya:

testdf2.LongMA = testdf2.LongMA -1

kolom LongMA di testdf akan memiliki nilai asli dan testdf2 akan memiliki nilai decrimented.

Penting untuk melacak perbedaannya seiring pertumbuhan rantai penghitungan dan salinan kerangka data memiliki siklus hidupnya sendiri.


0

Ya, di Pandas kami memiliki banyak fungsi yang memiliki parameter inplacetetapi secara default ditetapkan ke False.

Jadi, ketika Anda melakukannya df.dropna(axis='index', how='all', inplace=False)berpikir bahwa Anda tidak ingin mengubah orignial DataFrame, oleh karena itu ia malah membuat salinan baru untuk Anda dengan perubahan yang diperlukan.

Tapi, saat Anda mengubah inplaceparameter menjadiTrue

Maka itu setara dengan secara eksplisit mengatakan bahwa saya tidak ingin salinan baru DataFramealih - alih melakukan perubahan pada yang diberikanDataFrame

Ini memaksa penerjemah Python untuk tidak membuat yang baruDataFrame

Tetapi Anda juga dapat menghindari penggunaan inplaceparameter dengan menetapkan ulang hasilnya ke orignal DataFrame

df = df.dropna(axis='index', how='all')

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.