Aturan apa yang digunakan Panda untuk menghasilkan tampilan vs salinan?


119

Saya bingung tentang aturan yang digunakan Panda saat memutuskan bahwa pilihan dari kerangka data adalah salinan dari kerangka data asli, atau tampilan pada aslinya.

Jika saya punya, misalnya,

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

Saya mengerti bahwa querymengembalikan salinan sehingga sesuatu seperti

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40

tidak akan berpengaruh pada dataframe asli, df. Saya juga memahami bahwa skalar atau irisan bernama mengembalikan tampilan, sehingga tugas ke ini, seperti

df.iloc[3] = 70

atau

df.ix[1,'B':'E'] = 222

akan berubah df. Tapi saya bingung ketika sampai pada kasus yang lebih rumit. Sebagai contoh,

df[df.C <= df.B] = 7654321

berubah df, tapi

df[df.C <= df.B].ix[:,'B':'E']

tidak.

Apakah ada aturan sederhana yang digunakan Panda yang baru saja saya lewatkan? Apa yang terjadi dalam kasus khusus ini; dan khususnya, bagaimana cara mengubah semua nilai (atau subset nilai) dalam kerangka data yang memenuhi kueri tertentu (seperti yang saya coba lakukan pada contoh terakhir di atas)?


Catatan: Ini tidak sama dengan pertanyaan ini ; dan saya telah membaca dokumentasinya , tetapi saya tidak tercerahkan olehnya. Saya juga telah membaca pertanyaan "Terkait" tentang topik ini, tetapi saya masih kehilangan aturan sederhana yang digunakan Pandas, dan bagaimana saya akan menerapkannya - misalnya - mengubah nilai (atau subset nilai) dalam kerangka data yang memenuhi kueri tertentu.

Jawaban:


138

Berikut aturannya, penggantian selanjutnya:

  • Semua operasi menghasilkan salinan

  • Jika inplace=Truedisediakan, itu akan mengubah di tempat; hanya beberapa operasi yang mendukung ini

  • Pengindeks yang menyetel, misalnya .loc/.iloc/.iat/.atakan menyetel di tempat.

  • Pengindeks yang mendapatkan objek bertipe tunggal hampir selalu berupa tampilan (bergantung pada tata letak memori, mungkin itu bukan alasan mengapa ini tidak dapat diandalkan). Ini terutama untuk efisiensi. (contoh dari atas adalah untuk .query; ini akan selalu mengembalikan salinan seperti yang dievaluasi oleh numexpr)

  • Pengindeks yang mendapatkan objek berjenis banyak selalu merupakan salinan.

Contoh Anda tentang chained indexing

df[df.C <= df.B].loc[:,'B':'E']

tidak dijamin akan berhasil (dan karena itu Anda tidak boleh melakukan ini).

Sebaliknya lakukan:

df.loc[df.C <= df.B, 'B':'E']

karena ini lebih cepat dan akan selalu berhasil

Pengindeksan berantai adalah 2 operasi python terpisah dan karenanya tidak dapat dicegat dengan andal oleh panda (Anda seringkali akan mendapatkan SettingWithCopyWarning, tetapi itu juga tidak dapat dideteksi 100%). Dokumen pengembang , yang Anda tunjuk, menawarkan penjelasan yang jauh lebih lengkap.


3
.queryakan SELALU mengembalikan salinan karena apa yang dilakukannya (dan bukan tampilan), karena dievaluasi oleh n numexpr. Jadi saya akan menambahkan itu ke 'aturan'
Jeff

3
panda bergantung pada numpy untuk menentukan apakah tampilan dibuat. Dalam kasus dtype tunggal (yang bisa berupa 1-d untuk seri, 2-d untuk bingkai, dll). numpy dapat menghasilkan tampilan; itu tergantung pada apa yang Anda potong; terkadang Anda bisa melihat dan terkadang tidak. panda tidak bergantung pada fakta ini sama sekali karena tidak selalu jelas apakah tampilan dibuat. tetapi ini tidak masalah karena loc tidak bergantung pada ini saat menyetel. Namun, ketika pengindeksan berantai, ini sangat penting (dan karenanya mengapa pengindeksan berantai buruk)
Jeff

3
Terima kasih banyak Jeff, balasan Anda sangat berguna. Apa sumber / referensi Anda tentang topik ini?
Kamixave

4
Pertama-tama, terima kasih atas kerja bagus Anda! Dan kedua, jika Anda memiliki cukup waktu, saya pikir akan sangat bagus untuk menambahkan paragraf yang mirip dengan balasan utama Anda di dokumen.
Kamixave

2
tentu akan membutuhkan permintaan tarik untuk menambah / merevisi dokumen. lakukanlah.
Jeff
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.